javascript浏览器中的JavaScript线程
1、浏览器的事件循环
2、宏任务和微任务
1、定时器、ajax、DOM等的回调会加入宏任务
2、queueMicrotask、Promise then等加入到微任务里面
注:在执行任何的宏任务之前,都需要保证微任务队列已经被清空了。
3、Promise面试题
3.1
setTimeout(function () {
console.log("setTimeout1");
// 构造函数的代码是不会被加入到任务队列里面的,会被放入到main script,会被直接执行
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("promise1");
resolve();
}).then(function () {
console.log("then1");
});
setTimeout(function () {
console.log("setTimeout2");
});
console.log(2);
queueMicrotask(() => {
console.log("queueMicrotask");
});
new Promise(function (resolve) {
resolve();
}).then(function () {
console.log("then3");
});
//输出:
promise1
2
then1
queueMicrotask
then3
setTimeout1
then2
then4
setTimeout2
3.2
async function bar() {
console.log("2222222");
return new Promise((resolve) => {
resolve();
});
}
async function foo() {
console.log("1111111");
await bar();
// 3333的执行必须等到bar()调用了resovle才会执行。
// 因为调了resolve,所以可以3333是被放到then()里面了,被放到微任务里面
console.log("3333333");
}
foo();
console.log("4444444");
// 输出:
// 1111111
// 2222222
// 4444444
// 3333333
3.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, reject) {
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