一、任务队列和事件循环
任务指的就是js代码中的运行的代码。任务分为同步的任务和异步的任务。
同步任务例如:
function fn(){}
var a=new Array()
var b=fn()
console.log
异步任务例如:
setTimeout、then
下面用一个小实例来解释吧。
console.log(4)
setTimeout(()=>{console.log(1)},0)
setTimeout(()=>{console.log(2)},0)
var p1=new Promise((n1,n2)=>{n1(1000)})
p1.then(()=>{console.log(3)})
console.log(5)
那他们的打印先后顺序是什么呢?4,5,3,1,2
所以:同步的从上到下按顺序打印,异步的再执行。异步任务的队列优先级: 异步宏任务先执行 然后在执行异步微任务。
我在这里告诉你,then是微任务,setTimeout是宏任务,那为什么这里先执行了then的呢?
原因是:事件循环。任务开启后,内部执行的时候可能会有新的任务。
在这里then是第一轮的微任务,而setTimeout是下一轮的宏任务,所以then的先打印。
所以最终顺序是:
脚本运行===>执行第一个宏任务:
1. 先执行同步任务
2.添加新的宏任务到队列中,添加新的的异步微任务
3.执行异步微任务
练一练:
console.log(4)
setTimeout(() => {
setTimeout(()=>{console.log(6)},0)
console.log(1)
var p2 = new Promise((n1, n2) => {
n1(1000)
})
p2.then(()=>{console.log(7)})
}, 0)
setTimeout(() => {
setTimeout(() => {console.log(2)}, 200)
var p3 = new Promise((n1, n2) => {
n1(1000)
})
p3.then(()=>{console.log(8)})
console.log(2)
}, 0)
var p1 = new Promise((n1, n2) => {
n1(1000)
})
p1.then(() => {console.log(3)})
console.log(5)
答案为:4,5,3,1,7,2,8,6,2
二、实例挑战
setTimeout(() => {
console.log(0);
});
new Promise(resolve => {
console.log(1);
setTimeout(() => {
resolve();
var p1=new Promise((n1,n2)=>{n1(20)})
p1.then(() => console.log(2));
console.log(3);
setTimeout(()=>{console.log(9)},0)
});
new Promise((n1,n2)=>{n1(20)}).then(() => console.log(4));
}).then(() => {
console.log(5);
var p2=new Promise((n1,n2)=>{n1(20)})
p2.then(() => console.log(8));
setTimeout(() => console.log(6));
});
console.log(7);
打印:1,7,4,0,3,5,2,8,9,6