宏任务
JS的主线程,代码由上而下执行,包含
- 整体的同步代码
- settimeout(异步函数)
- setinterval (异步函数)
微任务
- process.nextTick
(node.js版的"setTimeout") - promise
- async-await
微任务优先级
node中存在优先级:process.nextTick()>Promise.then()>setImmediate。
执行过程
- 由上而下执行代码,
- 碰到宏任务的异步函数,将其回调函数注册并存放宏任务队列中,
- 碰到微任务的异步函数,将其回调函数注册并存放微任务队列中,
(promise会立即执行除了回调函数.then、.catch的同步代码,因为new promise()是一个同步的过程,实例化对象) - 等到宏任务执行完毕,再去微任务队列中按顺序执行微任务,
- 执行微任务的过程中,如果有新的微任务产生,会把新的微任务放到微任务队列中,
- 当微任务队列中的所有微任务(包括新的)执行完毕以后,一轮事件循环就结束了,
- 新的一轮事件循环就开始了,按顺序执行宏任务队列中的宏任务,并执行其对应的微任务,
(即宏任务队列中有10个宏任务等待执行,需要先执行第一个宏任务及其对应的微任务,才会执行第二个宏任务)
关于async await 需要注意的地方
- 情况1:假如await后边跟的是一个变量,则在执行完await的函数内容之后,会直接将后边的函数注册成为一个微任务
- 情况2:假如await后边跟的是一个异步函数,则在执行完await的函数内容之后,会跳出当前的async函数,执行其他的任务,当所有的任务完成再回来进行await后边的任务。
- 具体参考:https://juejin.cn/post/6844904079353708557
测试题
setTimeout(function() {
console.log('2');
process.nextTick(function() {
console.log('3');
})
new Promise(function(resolve) {
console.log('4');
resolve();
}).then(function() {
console.log('5')
})
})
process.nextTick(function() {
console.log('6');
})
new Promise(function(resolve) {
console.log('7');
resolve();
}).then(function() {
console.log('8')
})
setTimeout(function() {
console.log('9');
process.nextTick(function() {
console.log('10');
})
new Promise(function(resolve) {
console.log('11');
resolve();
}).then(function() {
console.log('12')
})
})