function main() {
console.log("S-1");
setTimeout(() => {
console.log("setTimeout");
}, 0);
new Promise((resolve, reject) => {
for (let i = 0; i < 10000000000; i++) {}
resolve("Promise");
}).then((res) => console.log(res));
console.log("S-2");
}
// Invoke function
main();
当我运行main()函数时,得到的输出是:
'S-1'
'S-2'
'Promise'
'setTimeout'
在记录'S-1‘之后,有一个很大的时间间隔,然后几秒钟后,其余的立即被记录。时间间隔不应该发生在测井'S-2‘之后吗?
发布于 2022-06-11 21:27:27
允诺构造函数内的函数与脚本的其余部分在同一(而且仅)主线程上同步运行。构建承诺并不会导致创建单独的线程。
如果在允诺构造函数中立即执行一些繁重的处理,则在将控制流返回到允诺构造函数的外部之前,必须完成该繁重的处理。在这种情况下,这意味着循环的多次迭代必须在此之前完成:
.then
处理程序。console.log("S-2");
行运行为了在不移动日志的情况下获得您想要或期望的输出,您必须将昂贵的代码卸载到不同的环境,例如工人或服务器(使用网络请求)。
发布于 2022-06-11 22:25:24
正如@CertainPerformance所说,Javascript只能处理一个调用堆栈。它需要一劳永逸地完成这个线程。对于承诺和超时,它使用作业和任务队列。事件循环对作业队列进行排序,然后对任务队列进行排序。
让我们试着理解您在调用堆栈和队列方面所写的内容。
function main() {
// 1. execute straight forward
console.log("S-1");
// 2. sets / schedules a timer, the anonymous function is then stored in the callback
setTimeout(() => {
console.log("setTimeout");
}, 0);
// 3. create a new Promise, with the constructor acting as executor
// executes immediately, as its designed to set the state of the Promise for the then() to react to.
new Promise((resolve, reject) => {
for (let i = 0; i < 10000000000; i++) {}
// 3.5 the resolve signals that the execution is finished
// either returns the promise or passes through the then()
resolve("Promise");
// 4. after the promise execution has been resolved,
// then() creates another anonymous function, and stores in the callback.
// at this point there are 2 entries in the callback
}).then((res) => console.log(res));
// 5. once the above Promise executor has been executed, execute this
console.log("S-2");
// By now, since both the timer and promise execution has been done,
// the timeout is put into the Task Queue and the Promise then() is put into the Job Queue.
}
// 0. puts this into the call stack and execute
main();
// 6. The event loop deques all of the call stack from the job queue and puts it into the main call stack to execute.
// hence, the then() is executed first
// 7. The event loop then deques all of the call stack from the task queue and puts it into the main call stack to execute.
// hence, the timeout function is executed next.
如果你想让它成为一个回调。
function main() {
console.log("S-1");
setTimeout(() => {
console.log("setTimeout");
}, 0);
new Promise((resolve, reject) => {
setTimeout(() => {
resolve("promise");
}, 1000);
}).then((res) => console.log(res));
console.log("S-2");
}
// Invoke function
main();
参考资料:https://medium.com/@idineshgarg/let-us-consider-an-example-a58bb1c11f55
https://stackoverflow.com/questions/72587907
复制相似问题