思考以下JS异步编程题中的执行顺序和结果:
async function async1() {
console.log("async1 start");
await async2();
console.log("async1 end");
}
async function async2() {
setTimeout(() => {
console.log('timer')
}, 0)
console.log("async2");
}
async1();
console.log("start")
结果如下:
async1 start
async2
start
async1 end
timer
async function async1 () {
console.log('async1 start');
await new Promise(resolve => {
console.log('promise1')
resolve('promise resolve')
})
console.log('async1 success');
return 'async1 end'
}
console.log('srcipt start')
async1().then(res => {
console.log(res)
})
new Promise(resolve => {
console.log('promise2')
setTimeout(() => {
console.log('timer')
})
})
结果如下:
srcipt start
async1 start
promise1
promise2
async1 success
async1 end
timer
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
async function testSometing() {
console.log("执行testSometing");
return "testSometing";
}
async function testAsync() {
console.log("执行testAsync");
return Promise.resolve("hello async");
}
async function test() {
console.log("test start...");
const v1 = await testSometing();
console.log(v1);
const v2 = await testAsync();
console.log(v2);
console.log(v1, v2);
}
test();
var promise = new Promise(resolve => {
console.log("promise start...");
resolve("promise");
});
promise.then(val => console.log(val));
console.log("test end...");
结果如下:
test start…
执行testSometing
promise start…
test end…
testSometing
执行testAsync
promise
hello async
testSometing hello async
async function async1 () {
await async2();
console.log('async1');
return 'async1 success'
}
async function async2 () {
return new Promise((resolve, reject) => {
console.log('async2')
reject('error')
})
}
async1().then(res => console.log(res))
结果如下:
‘async2’
Uncaught (in promise) error
const first = () => (new Promise((resolve, reject) => {
console.log(3);
let p = new Promise((resolve, reject) => {
console.log(7);
setTimeout(() => {
console.log(5);
resolve(6);
console.log(p)
}, 0)
resolve(1);
});
resolve(2);
p.then((arg) => {
console.log(arg);
});
}));
first().then((arg) => {
console.log(arg);
});
console.log(4);
结果如下:
3
7
4
1
2
5
Promise <fulfilled>1
var a;
var b = new Promise((resolve, reject) => {
console.log('promise1');
setTimeout(() => {
resolve();
}, 1000);
})
.then(() => {
console.log('promise2');
})
.then(() => {
console.log('promise3');
})
.then(() => {
console.log('promise4');
});
a = new Promise(async (resolve, reject) => {
console.log(a);
await b;
console.log(a);
console.log('after1');
await a;
resolve(true);
console.log('after2');
});
console.log('end');
结果如下:
promise1
undefined
end
promise2
promise3
promise4
Promise { <pending> }
after1
new Promise((resolve, reject) => {
resolve(2)
new Promise((resolve, reject) => {
resolve(5)
}).then((v) => {
console.log(v)
})
}).then((v) => {
console.log(v)
})
new Promise((resolve, reject) => {
setTimeout(() => {
resolve(2)
new Promise((resolve, reject) => {
resolve(5)
}).then((v) => {
console.log(v)
})
})
}).then((v) => {
console.log(v)
})
结果如下:
5
2
2
5
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(() => {
console.log(2);
process.nextTick(() => {
console.log(3);
});
new Promise((resolve) => {
console.log(4);
resolve();
}).then(() => {
console.log(5);
});
});
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);
});
});
分析:
事件循环相关基础
- 主线程先执行所有同步代码。
- 每一个 tick(事件循环)分为:
- 同步代码
- nextTick 队列(process.nextTick,在微任务队列之前,优先级最高)
- 微任务队列(Promise.then,queueMicrotask 等)
- 宏任务队列(setTimeout、setInterval、IO 等)
逐步分析执行过程
1. 同步代码优先执行
console.log(1); // 打印 1 setTimeout(...); // 加入宏任务队列1 new Promise(...); // 打印 7 process.nextTick(...); // 加入 nextTick 队列 setTimeout(...); // 加入宏任务队列2
执行顺序:
console.log(1)打印 1setTimeout(...)加入宏任务队列1new Promise(...)执行构造函数,打印 7,resolve()后.then(...)加入微任务队列process.nextTick(...)加入 nextTick 队列setTimeout(...)加入宏任务队列2
2. 主线程执行完毕,处理 nextTick 队列
只有一个:
console.log(6)打印 6
3. 处理 微任务队列(Promise.then)
只有一个:
console.log(8)打印 8
此时同步阶段结束,输出为:1 7 6 8
4. 进入 宏任务队列(setTimeout)
宏任务1(第一个 setTimeout)
console.log(2);
process.nextTick(() => { console.log(3); });
new Promise((resolve) => {
console.log(4);
resolve();
}).then(() => {
console.log(5);
});
console.log(2)打印 2process.nextTick(...)加入 nextTick 队列console.log(4)打印 4resolve()后.then(...)加入微任务队列
宏任务1内同步结束,输出:2 4
先处理 nextTick:
console.log(3)打印 3
再处理微任务:
console.log(5)打印 5
宏任务1阶段输出:2 4 3 5
宏任务2(第二个 setTimeout)
console.log(9);
process.nextTick(() => { console.log(10); });
new Promise((resolve) => {
console.log(11);
resolve();
}).then(() => {
console.log(12);
});
console.log(9)打印 9process.nextTick(...)加入 nextTick 队列console.log(11)打印 11resolve()后.then(...)加入微任务队列
宏任务2内同步结束,输出:9 11
先处理 nextTick:
console.log(10)打印 10
再处理微任务:
console.log(12)打印 12
宏任务2阶段输出:9 11 10 12
最终输出顺序:
1 7 6 8 2 4 3 5 9 11 10 12
原创文章,作者:czhdawn,如若转载,请注明出处:https://www.czhdawn.cn/archives/4959