MacroTask Queue
MacroTask Queue(宏任务队列)主要包括setTimeout, setInterval, setImmediate, requestAnimationFrame, UI rendeing, NodeJS中的`I/O等。
MicroTask Queue
MicroTask Queue(微任务队列)主要包括两类:
独立回调microTask:如Promise,其成功/失败回调函数相互独立;
复合回调microTask:如 Object.observe, MutationObserver 和NodeJs中的 process.nextTick ,不同状态回调在同一函数体;
MacroTask和MicroTask
1.依次执行同步代码直至执行完毕;
//这里JavaScript脚本执行也是一个macroTask,执行完毕后应该跳到第三步
2.检查MacroTask 队列,若有触发的异步任务,则取第一个并调用其事件处理函数,然后跳至第三步,若没有需处理的异步任务,则直接跳至第三步;
3.检查MicroTask队列,然后执行所有已触发的异步任务,依次执行事件处理函数,直至执行完毕,然后跳至第二步,若没有需处理的异步任务中,则直接返回第二步,依次执行后续步骤;
4.最后返回第二步,继续检查MacroTask队列,依次执行后续步骤;
5.如此往复,若所有异步任务处理完成,则结束;
process.nextTick
node中的process.nextTick方法可以在当前"执行栈"的尾部-下一次Event Loop(主线程读取"任务队列")之前----触发回调函数。也就是说,它指定的任务总是发生在所有异步任务之前。
console.log("start");
let promise1 = new Promise(function (resolve) {
console.log("promise1");
resolve();
console.log("promise1 end");
}).then(function () {
console.log("promise2");
});
setTimeout(function () {
console.log("settimeout");
});
console.log("end");
//start -> promise1 ->promise1 end -> end -> promise2 -> settimeout
async function async1() {
console.log("async1 start");
await async2();
console.log("async1 end");
}
async function async2() {
console.log("async2");
}
console.log("start");
async1();
console.log("end");
//async方法执行时遇到await,await后表达式会立即执行,后面的代码会放入微任务(promise)
//start -> async1 start -> async2 -> end -> async1 end
var p1 = new Promise(function (resolve, reject) {
console.log(1);
resolve(1);
});
setTimeout(function () {
console.log(2);
}, 0);
p1.then(function (value) {
console.log(3);
});
setTimeout(function () {
console.log(4);
}, 0);
// 1->3->2->4
setTimeout(function () {
console.log("s1");
}, 0);
var p1 = new Promise(function (resolve, reject) {
setTimeout(() => {
console.log("s2");
resolve(1);
}, 0);
});
setTimeout(function () {
console.log("s3");
}, 0);
for (var i = 0; i < 100; i++) {
(function (j) {
p1.then(function (value) {
console.log("pt-" + j);
});
})(i);
}
// s1->s2->pt-0->...->pt-99->s3
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 -> async1 end -> promise2 -> setTimeout
console.log(1);
setTimeout(function () {
console.log(2);
}, 0);
new Promise(function (resolve) {
console.log(3);
resolve(Date.now());
}).then(function () {
console.log(4);
});
console.log(5);
setTimeout(function () {
new Promise(function (resolve) {
console.log(6);
resolve(Date.now());
}).then(function () {
console.log(7);
});
}, 0);
//1 3 5 4 2 6 7
console.log(1);
var start = Date.now();
setTimeout(function () {
console.log(2);
}, 0);
setTimeout(function () {
console.log(4, Date.now() - start);
}, 400);
Promise.resolve().then(function () {
var sum = function (a, b) {
return Number(a) + Number(b);
};
var res = [];
for (var i = 0; i < 5000000; i++) {
var a = Math.floor(Math.random() * 100);
var b = Math.floor(Math.random() * 200);
res.push(sum(a, b));
}
res = res.sort();
console.log(3);
});
// 1 3 2 4
function A() {
return Promise.resolve(Date.now());
}
async function B() {
console.log(3);
let now = await A();
console.log(4);
}
console.log(1);
B();
console.log(2);
//1 3 2 4
console.log(1);
setTimeout(() => {
console.log(4);
}, 0);
let promise = new Promise((resolve) => {
console.log(3);
resolve();
})
.then((data) => {
console.log(100);
})
.then((data) => {
console.log(200);
});
console.log(2);
//1 3 2 100 200 4
console.log(1);
setTimeout(() => {
console.log(2);
new Promise((resolve) => {
console.log(4);
resolve();
}).then(() => {
console.log(5);
});
});
new Promise((resolve) => {
console.log(7);
resolve();
}).then(() => {
console.log(8);
});
setTimeout(() => {
console.log(9);
new Promise((resolve) => {
console.log(11);
resolve();
}).then(() => {
console.log(12);
});
});
//1 7 8 2 4 5 9 11 12
console.log(1);
setTimeout(() => {
console.log(2);
new Promise((resolve) => {
console.log(4);
resolve();
}).then(() => {
console.log(5);
});
process.nextTick(() => {
console.log(3);
});
});
new Promise((resolve) => {
console.log(7);
resolve();
}).then(() => {
console.log(8);
});
process.nextTick(() => {
console.log(6);
});
// 1 7 6 8 2 4 3 5
console.log(1);
setTimeout(() => {
console.log(2);
new Promise((resolve) => {
console.log(4);
resolve();
}).then(() => {
console.log(5);
});
process.nextTick(() => {
console.log(3);
});
});
new Promise((resolve) => {
console.log(7);
resolve();
}).then(() => {
console.log(8);
});
process.nextTick(() => {
console.log(6);
});
setTimeout(() => {
console.log(9);
process.nextTick(() => {
console.log(10);
});
new Promise((resolve) => {
console.log(11);
resolve();
}).then(() => {
console.log(12);
});
});
//1 7 6 8 2 4 3 5 9 11 10 12
参考链接:
https://juejin.cn/post/6844903655473152008
http://www.ruanyifeng.com/blog/2014/10/event-loop.html
网友评论