1. 引言
介绍宏任务和微任务的概念及作用
一、宏任务(Macro Task)
宏任务是指在 JavaScript 中需要等待整个脚本执行完毕后才会执行的任务。常见的宏任务包括:
- script(脚本):执行 JavaScript 代码。
- setTimeout 和 setInterval:用于设置延迟或定时执行的函数。
- I/O 操作:如文件读取、网络请求等。
- UI 渲染:浏览器重新渲染页面。
宏任务的作用是处理一些需要在整个脚本执行完毕后进行的操作,例如在页面加载完成后执行一些初始化代码、在用户操作后进行数据处理等。
二、微任务(Micro Task)
微任务是指在 JavaScript 中可以在当前任务执行完毕后立即执行的任务。常见的微任务包括:
- Promise 的回调函数:当 Promise 对象状态改变时(如 resolve 或 reject),注册的回调函数会被添加到微任务队列中。
- MutationObserver:用于监视 DOM 树的变化。
- Async/Await:异步函数的回调函数会被添加到微任务队列中。
微任务的作用是处理一些需要在当前任务执行完毕后立即执行的操作,例如在异步操作完成后进行后续处理、在用户操作后立即更新页面等。
宏任务和微任务的执行顺序是:先执行宏任务队列中的任务,当宏任务队列中的任务全部执行完毕后,再执行微任务队列中的任务。这种执行顺序确保了 JavaScript 代码的顺序执行,同时也提供了一种异步处理的方式。
2. 宏任务和微任务的区别和联系
对比两者的区别和联系
宏任务和微任务是 JavaScript 中的两个概念,它们在执行顺序和执行时机上有所不同。
- 宏任务(Macro Task):宏任务是指需要等待当前 JavaScript 事件循环结束后才能执行的任务。常见的宏任务包括:
setTimeout()
、setInterval()
、XMLHttpRequest
的回调函数、I/O 操作
等。宏任务会被放入事件队列中,等待当前事件循环的所有任务执行完毕后,才会按照事件队列中的顺序依次执行。 - 微任务(Micro Task):微任务是指可以在当前 JavaScript 事件循环中立即执行的任务。常见的微任务包括:
Promise
的回调函数、MutationObserver
的回调函数等。微任务会被放入微任务队列中,在当前事件循环的所有任务执行完毕后,会优先执行微任务队列中的任务,然后再执行事件队列中的宏任务。
宏任务和微任务的联系在于,它们都是 JavaScript 事件循环中的任务,都会按照一定的顺序执行。在执行顺序上,微任务会优先于宏任务执行。这意味着,如果在一个宏任务中创建了一个微任务,那么这个微任务会在当前事件循环中立即执行,而不会等待宏任务执行完毕。
3. 宏任务和微任务的执行顺序
阐述宏任务和微任务在事件循环中的执行顺序
宏任务和微任务在事件循环中的执行顺序如下:
- 执行当前事件循环中的所有宏任务。
- 检查微任务队列,如果有微任务,则执行微任务队列中的所有微任务。
- 如果有新的宏任务被添加到事件队列中,则回到步骤 1。
以示例说明不同类型任务的执行顺序
以下是一个简单的示例来说明不同类型任务的执行顺序:
console.log('start'); setTimeout(() => { console.log('timeout'); }, 0); Promise.resolve().then(() => { console.log('promise'); }); console.log('end');
在这个示例中,有三个任务:
console.log('start')
:这是一个宏任务,会在当前事件循环中立即执行。setTimeout(() => {console.log('timeout')}, 0)
:这是一个宏任务,它会被放入事件队列中,等待当前事件循环结束后执行。Promise.resolve().then(() => {console.log('promise')})
:这是一个微任务,它会被放入微任务队列中,在当前事件循环的所有任务执行完毕后立即执行。
因此,这个示例的输出结果是:
start end promise timeout
可以看到,微任务 promise
先于宏任务 timeout
执行。这是因为微任务会在当前事件循环的所有任务执行完毕后立即执行,而宏任务需要等待当前事件循环结束后才能执行。