async/await的执行顺序以及宏任务和微任务

一、async

带async关键字的函数,是声明异步函数,返回值是对象,如果async关键字函数返回的不是promise,会自动用Promise.resolve()包装。

返回值为 Promise {<resolved>: "test"}。

二、await

await等待右侧表达式的结果,这个结果是promise对象或者其他值。

如果它等到的不是一个 promise 对象,那 await 表达式的运算结果就是它等到的东西。

如果它等到的是一个 promise 对象,await 就忙起来了,它会阻塞后面的代码,等着 promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果。

由于test()造成的阻塞,console.log(end)会等到两秒后执行

所以为了避免造成阻塞,await 必须用在 async 函数中,async 函数调用不会造成阻塞。

三、async/await的执行顺序

遇到await会阻塞后面的代码,先执行async外面的同步代码,同步代码执行完,再回到async内部,继续执行await后面的代码。(好好理解一下上面的说明。也就是说,await只会阻塞当前async方法内的代码,不会影响外部代码的执行)

执行结果:

首先执行宏任务,执行test1函数,执行console.log(statr test1)

· 遇到await,先执行右边test2中的console.log(test2),中断了后面的代码,执行test1外面的同步代码

· 执行console.log(start async);

· 遇到setTimeout,推到到下个宏任务队列中

· 执行Promise里面的同步代码console.log(promise1)

· 运行到promise().then,发现是promise对象,推到微任务队列中

· 执行console.log(end async)

· test1外面的同步代码执行结束后,回到test1中,console.log(await test2())执行完成后返回Promise {<resolved>: "return test2 value"},是promise对象,推到微任务队列中

· 此时第一个宏任务结束,执行所有的微任务,因为微任务队列先进先出,所以先执行console.log(promise2),后执行console.log(return test2 value)

· 执行test2完成后,后面的代码不再阻塞,执行console.log(end test1);

· 执行下个宏任务,即执行console.log(setTimeout);

四、常见的宏任务和微任务

宏任务:script、setTimeOut、setInterval、setImmediate

微任务: promise.then,process.nextTick、Object.observe、MutationObserver

注意:Promise是同步任务

宏任务和微任务的执行顺序:

    执行宏任务script, 进入script后,所有的同步任务主线程执行 所有宏任务放入宏任务执行队列 所有微任务放入微任务执行队列 先清空微任务队列, 再取一个宏任务,执行,再清空微任务队列 依次循环
经验分享 程序员 微信小程序 职场和发展