bettersong / fe-nanjiu

关注公众号【前端南玖】每天一起学习!
107 stars 8 forks source link

day22-说说JS中异步有哪些方式? #91

Open bettersong opened 5 years ago

bettersong commented 5 years ago

众所周知JS是一门单线程语言,所谓单线程就是一次只能完成一个任务,如果有多个任务就必须排队,等上一个任务执行完才能执行下一个任务。 好处:实现起来比较简单,执行环境比较单纯。 坏处:如果有一个任务耗时特别长,那么它后面的任务就必须得等着,这样就会造成整个程序一直拖延执行,浏览器进入假死状态

为了解决这个问题,JS把任务执行的模式分为两种:同步和异步

同步:就是像上面那样,下一个任务必须等上一个任务执行完才能执行 异步:每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执行,所以程序的执行顺序与任务的排列顺序是不一致的、异步的。

下面说说几种常见的异步编程的方法:

1.回调函数:这是异步编程最基本的方法

/* 
    回调函数的优点是简单,容易部署,缺点是不利于代码的阅读和维护
*/
function fn(callback){
    console.log(1)
    setTimeout(() => {
        callback()
    })
    console.log(3)
}
function fn2(){
    console.log(2)
}
fn(fn2)

2.事件监听,JS中的所有事件都可以看作是异步任务,因为它只有触发了相应的事件才会执行(以jQuery为例)

// 事件监听
        function f1(){
            console.log(1)

            $(f1).trigger('done')

        }
        $(f1).on('done',function(){
            console.log(3)
        })

3.发布订阅模式,这种方法有点类似于事件监听,但比事件监听要更方便,代码更清晰(以jQuery为例)

jQuery.subscribe("done", f2);
function f1(){
    setTimeout(function () {
      // f1的任务代码
      jQuery.publish("done");
    }, 1000);
  }

4.es6的promise,这种方法被提出来就是为了解决回调函数嵌套多层造成回调地狱的

var p = new Promise((resovled,reject) => {
    console.log(1)
    setTimeout(() => {
        console.log(2)
    }, 1000);
    resovled()
})
p.then(() => {
    console.log(3)
}).catch(() => {
    console.log(4)
})
// 执行顺序:1  3   2

除了这些还有es6,es7中的Generator,async/await