所谓macroTask(宏任务)是指将任务排到下一个事件循环,microTask(微任务)是指将任务排到当前事件循环的队尾,执行时机会被宏任务更早。Promise的标准里没有规定Promise里的异步该使用哪种,但在node和浏览器的实现里都是使用的miroTask(微任务)
setTimeout(() => { console.log(1); }, 0) let p = Promise.resolve(2) p.then((val) => { console.log(val); })
宏任务api包括:setTimeout,setInterval,setImmediate(Node),requestAnimationFrame(浏览器),各种IO操作,网络请求
微任务api包括:process.nextTick(Node),MutationObserver(浏览器)
MutaionObserver演示:
let observer = new MutationObserver(()=>{ console.log(1); }) let node = document.createElement('div') observer.observe(node, { // 监听节点 childList: true // 一旦改变则触发回调函数 nextTickHandler }) node.innerHTML = 1
利用MutaionObserver封装一个微任务执行函数
let nextTick = (function () { let callbacks = [] function nextTickHandler() { let copies = callbacks.slice(0) callbacks = [] for (let i = 0; i < copies.length; i++) { copiesi } }
let counter = 1 let observer = new MutationObserver(nextTickHandler) // 声明 MO 和回调函数 let node = document.createElement('div') observer.observe(node, { // 监听节点 childList: true // 一旦改变则触发回调函数 nextTickHandler }) return function (cb) { callbacks.push(cb) counter = (counter + 1) % 2 //让节点内容文本在 1 和 0 间切换 node.innerHTML = counter } })()
小例题:
console.log(1)
setTimeout(function() {
console.log(2)
}, 0)
console.log(3)
宏任务: 主线程代码, setTimeout 等属于宏任务, 上一个宏任务执行完, 才会考虑执行下一个宏任务
微任务: promise .then .catch的需要执行的内容, 属于微任务, 满足条件的微任务, 会被添加到当前宏任务的最后去执行
事件循环队列 eventLoop
例题1:
console.log(1)
setTimeout(function() {
console.log(2) // 宏任务
}, 0)
const p = new Promise((resolve, reject) => {
resolve(1000)
})
p.then(data => {
console.log(data) // 微任务
})
console.log(3)
例题2:
async function fn () {
console.log(111)
}
fn()
console.log(222)
例题3:
async function fn () {
const res = await 2
console.log(res)
}
fn()
console.log(222)
例题4:
async function fn () {
console.log('嘿嘿')
const res = await fn2()
console.log(res) // 微任务
}
async function fn2 () {
console.log('gaga')
}
fn()
console.log(222)