本文深入解析JavaScript中的任务分类,重点阐述同步、异步(宏任务与微任务)的执行机制。通过对比setTimeout、Promise等典型场景,阐明事件循环中宏任务与微任务的调度规则及性能考量,帮助开发者准确掌握异步代码的执行顺序。
分类
JavaScript中的任务主要划分为两类:同步任务与异步任务。其中,异步任务进一步细分为宏任务和微任务。这两类任务分别维护独立的队列,遵循先进先出(FIFO)的原则进行处理。
同步任务是指在主线程上按顺序排队执行的操作。只有当前面的任务完全执行完毕后,后续的任务才会开始执行。
异步任务不直接进入主线程,而是被放置到“任务队列”中。只有当主线程上的所有同步任务执行完毕后,系统才会通知主线程去任务队列中请求并执行异步任务。

宏任务
常见的宏任务包括整体代码块(script)、setTimeout以及setInterval等。

部分资料提及UI Rendering也属于宏任务,但依据HTML规范文档的分析,这实际上是与微任务平行的一个独立操作步骤。
requestAnimationFrame姑且也算是宏任务吧,requestAnimationFrame,下次页面重绘前所执行的操作,而重绘也是作为宏任务的一个步骤来存在的,且该步骤晚于微任务的执行
宏任务是JavaScript执行的主流机制。当脚本开始运行时,即开启了一个宏任务,并在其中逐条执行指令。
宏任务可以存在多个,但它们会按照既定顺序依次执行。
每个宏任务执行完毕后,可以跟随一个微任务队列。如果该微任务队列中包含待执行的指令或方法,则立即执行;否则,系统将继续执行下一个宏任务,直到所有宏任务处理完毕。
微任务
典型的微任务包括Promise、async/await等异步操作。

需要特别注意,只有Promise中的then方法会被加入微任务队列,而Promise的resolve过程属于同步执行范畴。
在async函数中,await关键字之前的代码属于同步执行部分。当遇到await时,系统会执行await之后的函数,并返回一个Promise对象,同时将await下方的代码放入微任务队列,随后退出当前async函数的同步执行部分。
为什么
既然已有宏任务,为何还需要引入微任务机制?
主要原因是宏任务的开销较大。当某些方法已准备就绪,但希望其排在较后位置执行,且不希望为此新增一个宏任务时,可以将这些方法放入微任务队列。这样,在当前宏任务的代码执行完毕后,系统会立即执行微任务队列中的内容。
案例
console.log('整体script开始。');
setTimeout(()=>{
console.log('宏任务setTimeout的回调函数。')
})
Promise.resolve().then(function() {
console.log('微任务Promise回调函数1。')
}).then(function() {
console.log('微任务Promise回调函数2。')
})
console.log('整体script结束。')运行结果如下:
整体script开始。 整体script结束。 微任务Promise回调函数1。 微任务Promise回调函数2。 宏任务setTimeout的回调函数。
到此这篇关于JavaScript宏任务和微任务区别介绍的文章就介绍到这了,更多相关JS宏任务与微任务内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!