美文网首页
js处理异步的方式

js处理异步的方式

作者: 花开有声是我 | 来源:发表于2019-02-22 13:58 被阅读0次
    目前我所知的“异步模式”一共有4种方法,分别是

    一、回调函数
    二、 事件监听
    三、发布/订阅
    四、promise对象

    一、回调函数

    回调(callback)是一个函数被作为一个参数传递到另一个函数里,在那个函数执行完后再执行。( B函数被作为参数传递到A函数里,在A函数执行完后再执行B )
    假定有两个函数f1和f2,f2等待f1的执行结果,f1()-->f2();如果f1很耗时,可以改写f1,把f2写成f1的回调函数:

    function f1(callback){
      setTimeout(function () {
        callback(); // f1的任务代码
      }, 1000);
    }
    f1(f2);  // 执行
    

    采用回调的方式,把同步操作变成了异步操作,f1不会堵塞程序运行,相当于先执行程序的主要逻辑,将耗时的操作推迟执行。

    回调函数是异步编程最基本的方法,其优点是简单、容易理解和部署,缺点是不利于代码的阅读和维护,各个部分之间高度耦合,流程会很混乱,而且每个任务只能指定一个回调函数。

    注意 区分 回调函数和异步,回调是实现异步的一种手段,并不一定就是异步。
    回调也可以是同步,如:

    function A(callback){
        console.log("I am A");
        callback();  //调用该函数
    }
    function B(){
       console.log("I am B");
    }
    A(B);
    
    二、 事件监听

    采用事件驱动模式,任务的执行不取决代码的顺序,而取决于某一个事件是否发生。
    监听函数有:on,bind,listen,addEventListener,observe
    举例,为f1绑定一个事件(jquery写法):f1.on('done',f2);即当f1发生done事件,就执行f2。

    function f1(){
        settimeout(function(){
           // f1的任务代码
           f1.trigger('done');  // 执行完成后,立即触发done事件,从而开始执行f2
        },1000);
    }
    

    优点:易理解,可绑定多个事件,每一个事件可指定多个回调函数,可以去耦合,有利于实现模块化
    缺点:整个程序都要变成事件驱动型,运行流程会变得不清晰

    三、发布/订阅

    学习中,待补充

    四、promise对象

    Promises对象是CommonJS工作组提出的一种规范,目的是为异步编程提供统一接口
    每一个异步任务返回一个Promise对象,该对象有一个then方法,允许指定回调函数。比如,f1的回调函数f2,可以写成:

     f1().then(f2);
    

    all的用法:

    let p1 = new Promise((resolve, reject) => {
            console.log('begin p1');
            setTimeout(() => {
                console.log('end p1');
                resolve('p1');
            }, 2);
        });
        p1.then(() => {
            console.log('then p1');
        })
        let p2 = new Promise((resolve, reject) => {
            console.log('begin p2');
            setTimeout(() => {
                console.log('end p2');
                resolve('p2');
            }, 3);
        })
        p2.then(() => {
            console.log('then p2');
        })
        setTimeout(() => {
            console.log('setTimeout: p3');
            let p3 = Promise.all([p1, p2]).then((datas) => {
                console.log('begin p3');
                console.log('end p3');
            });
            p3.then(() => {
                console.log('then p3');
            });
        }, 1);
    
        console.log('mark p4');
        // begin p1
        // begin p2
        // mark p4
        // setTimeout: p3
        // end p1
        // then p1
        // end p2
        // then p2
        // begin p3
        // end p3
        // then p3
    

    参考链接:
    https://www.cnblogs.com/zuobaiquan01/p/8477322.html
    http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html
    https://www.cnblogs.com/chengxs/p/6497575.html
    http://mp.weixin.qq.com/s?__biz=MzAwNTAzMjcxNg==&mid=2651425195&idx=1&sn=eed6bea35323c75f0c43ae61818c0a55&chksm=80dff7c8b7a87edeb834cc4aabf0eec40c7566b45abd5c58b56625dc0efd77d15c9e64534140&mpshare=1&scene=1&srcid=02260hYIB6d5lSLVwyvPIUWX#rd
    https://segmentfault.com/a/1190000008489550

    相关文章

      网友评论

          本文标题:js处理异步的方式

          本文链接:https://www.haomeiwen.com/subject/rifeyqtx.html