在JavaScript中,任务可以分为两种类型,即宏任务和微任务。
宏任务指的是由浏览器提供的任务队列,比如事件处理、定时器等。调用栈为空时,才会执行宏任务队列中的任务,即每个宏任务只会执行一次。
而微任务是指在当前任务执行结束后立即执行的任务,比如Promise、async/await等。当一个宏任务执行完成后,会先执行所有的微任务,再执行下一个宏任务。
具体来说,当一个宏任务执行时,其内部产生的微任务会被放入微任务队列中,而当宏任务执行完成后,才会执行微任务队列中的所有微任务,直到队列为空后,才会开始执行下一个宏任务。
举个例子:
console.log('1') // 宏任务1
setTimeout(function() {
console.log('2') // 新的宏任务
Promise.resolve().then(function() {
console.log('3') // 微任务
})
}, 0)
Promise.resolve().then(function() {
console.log('4') // 微任务
})
console.log('5') // 宏任务2
执行顺序如下:
- 首先执行第一个宏任务,输出1;
- 遇到setTimeout,将其中的函数放入宏任务队列中;
- 遇到Promise.resolve(),将其中的函数放入微任务队列中;
- 输出5;
- 第一个宏任务执行完成,开始执行微任务队列,输出4,再输出3;
- 微任务队列执行完毕,执行下一个宏任务,输出2。
总结一下,我们可以通过控制微任务队列和宏任务队列的改变来优化程序的执行顺序,提高程序的性能。