初窥async,await

首先是一道今日头条的面试题:(据说是今日头条的而且已经烂大街了)javascript

 1     async function async1() {
 2         console.log( 'async1 start' )
 3         await async2()
 4         console.log( 'async1 end' )
 5     }
 6     
 7     async function async2() {
 8         console.log( 'async2' )
 9     }
10     
11     console.log( 'script start' )
12     
13     setTimeout( function () {
14         console.log( 'setTimeout' )
15     }, 0 )
16     
17     async1();
18     
19     new Promise( function ( resolve ) {
20         console.log( 'promise1' )
21         resolve();
22     } ).then( function () {
23         console.log( 'promise2' )
24     } )
25     
26     console.log( 'script end' )

这个题我认为的顺序和浏览器的顺序一开始并不同,让我一度觉得浏览器出了问题。java

首先须要了解promise,否则后面就很难理解下去。参见:http://es6.ruanyifeng.com/#docs/promisees6

async是什么?

 简单来说若是一个函数前面带了async那么,函数的返回值一定是一个promise的对象。若是返回值不是promise对象,会自动的去包装为一个promise对象。面试

await是什么?

 await能够算是async wait简写。等待async执行结果。promise

回到代码中,显而易见首先打印的内容是‘script start’,不须要解释。浏览器

而后就是setTimeout,虽然时间是0可是只有在这一轮事件循环的底部或者是事件队列为空才会当即执行,很明显既不是底部,事件队列也还未执行完成。async

下一个执行到async1();函数

async1中首先打印async1 start’,而后遇到await,await会阻塞后面的代码,先执行async外部的代码,因此会接着打印‘async2’;spa

以前的await中断了当前async的执行,因此下一个执行的就是promise,promise是直接调用同步代码,因此接着就是‘promise1’;code

由于会优先执行同步代码,因此接下来就是打印‘script end’;

执行完毕回到promise接着执行then打印‘promise2’,以后再次回到前面继续执行resolve,可是由于参数为空,因此打印‘undefined’;(promise执行顺序,具体参见:http://es6.ruanyifeng.com/#docs/promise)

这个时候await async2()执行结束,继续async1后面的代码,打印‘async1 end’;

至此因此的事件队列执行结束

前面说了,事件队列为空才会执行setTimeout

因此正确的顺序为:

    script start
    async1 start
    async2
    promise1
    script end
    promise2
    async1 end
    setTimeout

 有错误的话欢迎指正。 

相关文章
相关标签/搜索