宏任务
(1)分类 : setTimeout () setInterval () requestAnimationFrame () I/O
(2)特点 :
1.宏任务所处的队列即为宏任务队列。
2.第一个宏任务队列只有一个任务,执行主线程中的js代码。
3.宏任务队列可以有多个。
4.当宏任务队列中的任务执行完毕后,会查看是否有微任务队列,有则执行微任务队列中的任务,没有则查看是否有宏任务队列
微任务
(1)分类 : Promise中的回调函数.then(),Promise本身是同步任务,process.nextTick Object.observe, MutationObserver
(2)特点 :
1.微任务所处的队列即为微任务队列
2.只有一个微任务队列
3.在上一个宏任务队列执行完毕之后如果有微任务队列就会执行微任务队列中的所有任务
例题一
setTimeout(()=>{
console.log("setTimeout"); //宏任务,加入宏任务队列,等待执行
},0);
new Promise((resolve,reject)=>{
for(var i=0;i<5;i++){
console.log(i); //主线程任务,直接执行,打印1 2 3 4 5
}
resolve() //修改promise状态为成功
}).then(()=>{
console.log("promise回调函数"); //微任务,加入微任务队列等待执行
})
console.log("end"); //主线程任务,直接执行,打印 "end"
//接着执行微任务队列中的任务,打印 "promise回调函数"
//最后执行宏任务队列中的任务,打印 "setTimeout"
//start
1
2
3
4
5
end
promise回调函数
setTimeout
例题二
setTimeout(() => {
console.log('setTimeout'); // 将回调代码放入个宏任务队列,第二轮宏任务执行
}, 0);
new Promise((resolve, reject) => {
console.log('---Promise第一轮微任务同步执行---'); //第一轮微任务同步执行
resolve()
}).then(() => {
console.log('Promise.then实例成功回调执行'); // 将回调代码放入微任务队列,第一轮宏任务执行完后立即执行
});
console.log('---end---'); //第一轮主线程结束
</script>
// ---start---
---Promise第一轮微任务同步执行---
---end---
Promise.then实例成功回调执行
setTimeout
例题三
setTimeout(function() {
console.log('1')
}); //宏任务,分发到宏任务的Event Queue中等待执行
new Promise(function(resolve) {
console.log('2'); //主线程任务,直接执行,打印 2
resolve();
}).then(function() {
console.log('3') //.then()中的方法属于微任务,分发到微任务的Event Queue中等待执行
});
console.log('4'); //主线程任务,直接执行,打印 4
new Promise(function(resolve) {
console.log('5'); //主线程任务,直接执行,打印 5
resolve();
}).then(function() {
console.log('6') //,then()中的方法是微任务,分发到微任务Event Queue中等待执行
});
setTimeout(function() {
console.log('7') //宏任务,分发到宏任务的Event Queue中等待执行
});
function bar() {
console.log('8') //主线程任务,直接执行,打印 8
foo() //调用foo(),属于主线程任务,直接执行,打印 9
}
function foo() {
console.log('9')
}
console.log('10') //主线程任务,直接执行,打印 10
bar() //10在8 9之前打印,因为js代码是从上到下依次执行,因此console.log(10)先执行
//接着执行微任务队列中的任务,先进先执行,依次打印 3 6
//最后执行宏任务队列中的任务,先进先执行,一次打印 1 7
//结果为 2 4 5 10 8 9 3 6 1 7
</script>