js处理异步的方式

2019-02-22  本文已影响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

上一篇下一篇

猜你喜欢

热点阅读