zoukankan      html  css  js  c++  java
  • JavaScript异步编程的方法

    异步编程

    在浏览器端,异步编程非常重要,耗时很长的操作都应该异步执行,避免浏览器失去响应。最常见的例子就是通过AJAX向服务器发送异步请求。

    异步编程有很多种方法

    1、回调函数

    比如有两个函数
    f1();
    f2();//f2依赖于f1的执行状态
    如果f1耗时很长,它会阻塞后面程序的运行
    我们利用setTimeout来改写f1,因为setTimeout是异步的

    function f1(callback){
        setTimeout(function(){
            //f1的代码,耗时很长,这里是又开启了一个线程,
            callback();//f1完后执行callback()
        },1000)
    }
    
    f1(f2);//这段代码不会阻塞后面的程序运行,f2依赖于f1的执行状态

    采用这种方式,我们把同步操作变成了异步操作,f1不会堵塞程序运行,相当于先执行程序的主要逻辑,将耗时的操作推迟执行。
    这种方法很简单,也容易理解,但是不利于代码的阅读和维护,各个部分之间高度耦合,而且每个任务只能指定一个回调函数

    2、事件监听
    另一种思路是采用事件驱动模式。任务的执行不取决于代码的顺序,而取决于某个事件是否发生。

    f1.on('done',f2);//为f1绑定一个事件(f2订阅事件)
    function f1(){
        setTimeout(function(){
            //f1的代码
            f1.trigger('done');//f1触发这个事件(f1发布事件)
        },1000)
    }

    这种方法可以绑定多个事件,每个事件可以指定多个回调函数,而且可以"去耦合"有利于实现模块化。
    缺点是整个程序都要变成事件驱动型,运行流程会变得很不清晰。

    3.发布订阅模式
    又称观察者模式,它广泛的应用于异步编程中,是一种代替回调函数的方案。
    上面讲到的事件,可以理解成“信号”
    假定,存在一个"信号中心",某个任务执行完成,就向信号中心"发布"一个信号,其他任务可以向信号中心"订阅"这个信号,从而知道什么时候自己可以开始执行。
    这就叫做"发布/订阅模式",又称"观察者模式"
    发布订阅者模式可以去除对象之间的耦合,有利于实现模块化,而且我们可以通过查看"消息中心",了解存在多少信号、每个信号有多少订阅者,从而监控程序的运行。

    这个模式有多种实现,下面采用的是jQuery的一个插件。

    //f2向"信号中心"jQuery订阅"done"信号
    jQuery.subscribe("done", f2);
    function f1(){
        setTimeout(function () {
          // f1的任务代码
          jQuery.publish("done");//f1执行完成后,向"信号中心"jQuery发布"done"信号,从而引发f2的执行。
        }, 1000);
      }

    4.Promise对象
    Promises对象是CommonJS工作组提出的一种规范,目的是为异步编程提供统一接口,使得控制异步操作更加的容易
    ES6将Promsie纳入了规范,并原生提供了Promise对象
    简单说,它的思想是,每一个异步任务返回一个Promise对象,该对象有一个then方法,允许指定回调函数。比如,f1的回调函数f2,可以写成:
    f1().then(f2);
    promise优点在于避免层层嵌套的回调函数,回调函数变成了链式写法,程序的流程可以看得很清楚,并且提供了统一的接口,使得控制异步操作更加的容易。
    而且,它还有一个前面三种方法都没有的好处:如果一个任务已经完成,再添加回调函数,该回调函数会立即执行。所以,你不用担心是否错过了某个事件或信号。
    这种方法的缺点就是编写和理解,都相对比较难。

    例子:我们用promise对象实现AJAX操作

    var getJSON=function(url){
        var promise=new Promise(function(resolve,reject){
            //AJAX操作
            $.ajax({
                url:url,
                type:'GET',
                dataType:'json',
                success:function(data,status,xhr){
                    resolve(data);
                },
                error:function(xhr,textStatus){
                    reject(textStatus);
                }
            })
        })
        return promise;
    }
    getJSON('/post.json')
        //任务Resolve状态的回调函数,返回是这个promise对象
        .then(function(value) {
            console.log(value);
        })
        //任务Rejected状态的回调函数
        .catch(function(error){
            console.log(error);
        })

    采用链式的then方法可以指定按照次序调用的回调函数
    如果前一个回调函数返回的是另外一个promise对象,那么后一个回调函数就会等待该promise对象状态发生变化再调用

    getJSON("url1")
        .then(function(value){
             return getJSON(value.url2);//返回另外一个promise对象
         })
         //另外一个promise对象Resolve状态的回调函数
        .then(function(value){
            console.log(value)
        })
  • 相关阅读:
    稳扎稳打Silverlight(47) 4.0UI之操作剪切板, 隐式样式, CompositeTransform, 拖放外部文件到程序中
    返璞归真 asp.net mvc (9) asp.net mvc 3.0 新特性之 View(Razor)
    返璞归真 asp.net mvc (6) asp.net mvc 2.0 新特性
    稳扎稳打Silverlight(48) 4.0其它之打印, 动态绑定, 增强的导航系统, 杂七杂八
    精进不休 .NET 4.0 (9) ADO.NET Entity Framework 4.1 之 Code First
    稳扎稳打Silverlight(42) 4.0控件之Viewbox, RichTextBox
    稳扎稳打Silverlight(53) 4.0通信之对WCF NetTcpBinding的支持, 在Socket通信中通过HTTP检索策略文件, HTTP请求中的ClientHttp和BrowserHttp
    稳扎稳打 Silverlight 4.0 系列文章索引
    稳扎稳打Silverlight(54) 4.0通信之对UDP协议的支持: 通过 UdpAnySourceMulticastClient 实现 ASM(Any Source Multicast),即“任意源多播”
    返璞归真 asp.net mvc (8) asp.net mvc 3.0 新特性之 Model
  • 原文地址:https://www.cnblogs.com/t1amo/p/6851979.html
Copyright © 2011-2022 走看看