什么是宏任务和微任务
宏任务和微任务是在事件循环中执行的两种不同类型的任务。
宏任务是相对较大的任务,通常包括定时器任务(setTimeout、setInterval)、网络请求、用户交互事件(点击、滚动等)。宏任务会被添加到事件队列中,在每个事件循环中执行一次。
微任务是相对较小的任务,通常包括Promise回调、DOM变动观察器。微任务会在当前宏任务执行完毕后立即执行,而不会添加到事件队列中。微任务的执行时机是在当前宏任务的末尾,在下一个宏任务之前。
因此,微任务比宏任务具有更高的优先级,可以在用户交互之前或渲染之前得到及时处理,可以用于执行一些需要优先处理的任务,如更新DOM、处理异步操作的结果等。
总结起来,宏任务是事件循环中的较大任务,微任务是较小的任务,他们的执行顺序不同,微任务比宏任务的优先级更高。
宏任务有哪些
宏任务包括但不限于以下几种常见的任务:
1、定时器任务: 如setTimeout、setInterval
2、I/O任务:例如网络请求、文件读写等需要进行I/O操作的任务
3、用户交互任务:例如点击事件、输入事件等与用户交互的相关任务
4、渲染任务:当浏览器需要重绘或重新布局时触发的任务
5、请求动画帧任务:通过requestAnimationFrame()方法设置的任务,用于在每一帧进行绘画或动画操作
这些任务都是比较耗时的操作,在事件循环中被视为宏任务,需要等待一定时间或特定的触发条件才会执行
微任务有哪些
1、Promise回调:Promise对象的resolve或reject方法的回调函数
2、MutationObserver回调:当DOM发生变化时触发的回调函数
3、Promise的then()回调:Promise对象的then()方法中的回调函数
4、async/await函数中的后续操作:在async函数中使用await等待的操作完成后,紧接着的代码块中的任务
这些任务通常是较小且轻量级的操作,执行时间较短,适合在当前宏任务执行完毕后立即执行。由于微任务的执行时机在每个宏任务执行的过程中,因此可以保证在用户交互之前或渲染之前得到及时处理
const test = new Promise((resolve, reject) => {
console.log('new Promise')
resolve('success')
})
test.then((val) => {
console.log(val)
})
console.log('finish')
输出顺序为:
1、new Promise
2、finish
3、success
const test = new Promise((resolve, reject) => {
console.log(1)
console.log(2)
})
test.then(() => {
console.log(3)
})
console.log(4)
// 输出结果为
// 1
// 2
// 4
// 3不会输出,因为promise.then是微任务,会在所有的宏任务执行完成后才会执行,同时需要promise内部的状态发生变化,因为这里内部没有发生变化,所以不输出3
const promise1 = new Promise((resolve, reject) => {
console.log('promise1')
resolve('resolvel')
})
const promise2 = promise1.then(res => {
console.log(res)
})
console.log('1', promise1)
console.log('2', promise2)
// 输出结果为
// 1、promise1
// 将promise1.then放入微任务
// 2、'1' Promise {'resolve'},这里打印的是状态
// 2、'2' Promise {'pending'},这里打印的是状态
// 3、resolve
const promise = new Promise((resolve, reject) => {
console.log(1)
setTimeout(() => {
console.log('timerStart')
resolve('success')
console.log('timerEnd')
}, 0)
console.log(2)
})
promise.then((res) => {
console.log(res)
})
console.log(4)
// 1
// 2
// 4
// 开始
// 结束
// 成功
console.log('start')
const fn = () => {
return new Promise((resolve, reject) => {
console.log(1)
resolve(2)
})
}
console.log(3)
fn().then(res => {
console.log(res)
})
console.log('end')
// start
// 3
// 1
// end
// 2