今天在学node的时候有讲到浏览器中事件循环,大概整体流程也就是如下图
需要明确此几个概念
1.首选整个的事件的循环叫做一个tick,就是上图中整个的一个流程,从js脚本到宏任务、微任务队列再到栈。
2.事件循环中的共有两种任务,一个是上图中的TaskQueue宏任务,另外一个则是MicroataskQueue微任务。
3.常见的微任务队列的任务有:promise.then(),process.nextTick等任务
4.常见的宏任务队列则有:setTimeOut()、setInteval()等任务
5.宏任务想要执行的话必须要等微任务 *全部* 执行完毕后再能执行
接下来不多BB直接上面试题
面试题一
setTimeout(()=>{
console.log("1")
Promise.resolve().then(()=>{
console.log("2")
})
})
console.log("3")
Promise.resolve().then(()=>{
console.log("4")
setTimeout(()=>{
console.log("5")
})
})
分析一下上面的代码
第一个执行的是setTimeout,setTimeOut是一个宏任务,所以会先放到宏任务队列(注意:现在还不会执行,因为js脚本代码还没有执行完)
第二个执行的是console.log(“3”) //此时会直接输出3
第三个执行的是promise.resolve(),此时的then是一个微任务,所以会放到微任务队列(此时也不会执行)
js脚本代码代码执行完毕后就会先执行微任务队列中的任务
第四个执行的是微任务队列中的console.log(“4”)//此时会直接输出4
但此函数还没有执行完,后面还接了一个定时器函数,又因为此函数是一个宏任务,所以也会放到宏任务队列中去(此任务排在第二个执行)
此时微任务队列已经没有任务了,则会开始执行宏任务队列
首先执行的就是上面的setTimeout(),会直接输出 1
后面接了一个promise.then,这个函数就被放到了微任务队列中,因为微任务队列中有任务了就会先执行微任务队列,那么就会输出2
最后执行宏任务队列的定时器,则输出 5
因此最后输出的结果为 3 4 1 2 5
最后放两道面试题留给大家思考思考
面试题二
setTimeout(function () {
console.log("set1");
new Promise(function (resolve) {
resolve();
}).then(function () {
new Promise(function (resolve) {
resolve();
}).then(function () {
console.log("then4");
});
console.log("then2");
});
});
new Promise(function (resolve) {
console.log("pr1");
resolve();
}).then(function () {
console.log("then1");
});
setTimeout(function () {
console.log("set2");
});
console.log(2);
queueMicrotask(() => {
console.log("queueMicrotask1")
});
new Promise(function (resolve) {
resolve();
}).then(function () {
console.log("then3");
});
// pr1
// 2
// then1
// queuemicrotask1
// then3
// set1
// then2
// then4
// set2
面试题3
async function async1 () {
console.log('async1 start')
await async2();
console.log('async1 end')
}
async function async2 () {
console.log('async2')
}
console.log('script start')
setTimeout(function () {
console.log('setTimeout')
}, 0)
async1();
new Promise (function (resolve) {
console.log('promise1')
resolve();
}).then (function () {
console.log('promise2')
})
console.log('script end')
// script start
// async1 start
// async2
// promise1
// script end
// aysnc1 end
// promise2
// setToueout