异步任务执行顺序

常见的异步 async/await promise setTimeout 执行顺序问题,通过一道题来看看具体顺序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

async function async1() {
console.log('async1 start');
await async2();
console.log('asnyc1 end');
}
async function async2() {
console.log('async2');
}
console.log('script start');
setTimeout(() => {
console.log('setTimeOut');
}, 0);
async1();
new Promise(function (reslove) {
console.log('promise1');
reslove();
}).then(function () {
console.log('promise2');
})
console.log('script end');

执行结果

1
2
3
4
5
6
7
8
script start
async1 start
async2
promise1
script end
asnyc1 end
promise2
setTimeOut

js 中 eventLoop 事件循环机制

微任务 microtasks (JavaScript 引擎内部的微任务)

  • process.nextTick
  • Promises.then
  • Object.observe
  • MutationObserver

宏任务 macrotasks(宿主环境(浏览器/node)提供的一些 webapi)

  • script(整体代码)
  • setTimeout/setInterval
  • setImmediate(node 环境提供的)
  • I/O
  • UI rendering
  • event listner

执行顺序

首先执行 js 整体代码这个宏任务,同步代码会依次执行,过程中有微任务或者宏任务都会放到对应的任务队列中。
然后将微任务队列中的微任务全部取出执行。
最后去宏任务队列中取一个任务执行,结束后会监测微任务队列中有没有待执行的任务。

易混的概念

  • new Promise()中的处理器函数是同步执行(上面的 promise1),但是.then()是异步函数会放到微任务队列中
  • async 函数中如果没有 await 执行起来和普通的函数一样
  • await 后面的代码会同步执行完成。然后会让出线程,阻塞 async 内后续的代码,去执行 async 外的代码,等外面的同步代码执行完成,才会执行 async 中 await 后续的代码

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!