宏任务和微任务
执行顺序
- 同步-异步(异步分为宏任务(task)和微任务(jobs))先完成宏任务,再完成微任务
宏任务 | 微任务 |
---|
setTimeout | promise.then(catch,finally) |
setInterval | mutationObserver (监视dom变化) |
MessageChannel( 接口允许我们创建一个新的消息通道,并通过它的两个 MessagePort 属性发送数据。) | |
script | |
- 先执行同步代码,遇到异步宏任务则将异步宏任务放入宏任务队列中,遇到异步微任务则将异步微任务放入微任务队列中,当所有同步代码执行完毕后,再将异步微任务从队列中调入主线程执行,微任务执行完毕后再将异步宏任务从队列中调入主线程执行,一直循环直至所有任务执行完毕。
- 示例
console.log(1);
setTimeout(()=>{
console.log(2);
});
new Promise((res,rej)=>{
res(3);
console.log(4);
}).then(data=>{
console.log(data);
})
setTimeout(()=>{
console.log(1);
new Promise((res,rej)=>{
res(2);
console.log(3);
}).then(data => {
console.log(data);
});
});
new Promise(res=>{
res(4);
}).then((data)=>{
console.log(data);
setTimeout(()=>{
console.log(5);
});
});
console.log(6)
- aynsc , await 控制异步代码执行顺序,await之后的代码直接放入微任务队列
```javascript
async function async1(){
console.log('async1') //第一步直接输出
await async2();
console.log('async3')//await之后代码进入微任务队列,由于最先放入微任务队列,第五步打印
}
async1()//执行async1函数
console.log('script1');//同步代码直接执行。第三步打印
setTimeout(()=>{
console.log('setTimeout1') // 放入宏任务队列,等待下一次循环执行 后放 第八步打印
});
async function async2(){
console.log('async2'); //同步按顺序第二步打印
setTimeout(()=>{
console.log('async4') // 放入宏任务队列,等待下一次循环执行 先放 第二轮先执行宏任务,第七步打印
})
}
new Promise((res,rej)=>{
console.log('promise1'); //同步按顺序第四步打印
res('promise2')
}).then((res)=>{
console.log(res)//代码放入入微任务队列,第六步打印
})
//结果 async1 async2 script1 promise1 async3 promise2 async4 setTimeout1
```
4. 第一点:当微任务执行过程中出现了宏任务
将宏任务放入宏队列中,等当前微任务队列执行完毕后,再执行宏任务队列
第二点:当宏任务执行过程中,出现了微任务(此时,宏任务队列还没有清空)
将当前出现的微任务加入微队列中,将当前宏任务执行结束后,**再次清空微队列
setTimeout(()=>{
console.log('宏任务1');
new Promise((resolve)=>{
resolve(1)
}).then((res)=>{
console.log('微任务1');
setTimeout(()=>{
console.log('宏任务2')
})
new Promise((resolve)=>{
resolve(2)
}).then(res=>{
console.log('微任务2');
})
})
})
})
})
})