同步任务(js执行栈/回调栈) 异步任务(宏任务(宿主环境) 微任务(js引擎))
setTimeout为异步宏任务的,进任务队列排队
new promise为同步任务,进执行栈
.then .catch async(本身是同步任务)/await(await后边的都是异步的微任务)为微任务
先执行同步任务,再执行微任务异步任务,最后执行宏任务异步任务
例子:
setTimeout(() => {
console.log("4");
setTimeout(() => {
console.log("8");
}, 0);
new Promise((r) => {
console.log("5"); //构造函数是同步的
r();
}).then(() => {
console.log("7"); //then()是异步的,这里已经入队
});
console.log("6");
}, 0);
new Promise((r) => {
console.log("1"); //构造函数是同步的
r();
}).then(() => {
console.log("3"); //then()是异步的,这里已经入队
});
console.log("2");
输出顺序:1 2 3 4 5 6 7 8
setTimeout(function () {
console.log('1');
});
new Promise(function (resolve) {
console.log('2');
resolve();
}).then(function () {
console.log('3');
});
console.log('4');
//输出顺序:2 4 3 1
setTimeout(() => {
new Promise(resolve => {
resolve();
}).then(() => {
console.log('test');
});
console.log(4);
});
new Promise(resolve => {
resolve();
console.log(1)
}).then(() => {
console.log(3);
Promise.resolve().then(() => {
console.log('before timeout');
}).then(() => {
Promise.resolve().then(() => {
console.log('also before timeout')
})
})
})
console.log(2);
//输出:1 2 3 before timeout also before timeout 4 test
解释:
遇到setTimeout,异步宏任务,将() => {console.log(4)}放入宏任务队列中;
遇到new Promise,Promise在实例化的过程中所执行的代码都是同步进行的,所以输出1;
而Promise.then中注册的回调才是异步执行的,将其放入微任务队列中
遇到同步任务console.log(2),输出2;主线程中同步任务执行完
从微任务队列中取出任务到主线程中,输出3,此微任务中又有微任务,Promise.resolve().then(微任务a).then(微任务b),将其依次放入微任务队列中;
从微任务队列中取出任务a到主线程中,输出 before timeout;
从微任务队列中取出任务b到主线程中,任务b又注册了一个微任务c,放入微任务队列中;
从微任务队列中取出任务c到主线程中,输出 also before timeout;微任务队列为空
从宏任务队列中取出任务到主线程,此任务中注册了一个微任务d,将其放入微任务队列中,接下来遇到输出4,宏任务队列为空
从微任务队列中取出任务d到主线程 ,输出test,微任务队列为空,结束