首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么承诺保持调用堆栈的执行?

为什么承诺保持调用堆栈的执行?
EN

Stack Overflow用户
提问于 2022-06-11 21:19:24
回答 2查看 278关注 0票数 -1
代码语言:javascript
运行
复制
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()函数时,得到的输出是:

代码语言:javascript
运行
复制
'S-1'
'S-2'
'Promise'
'setTimeout'

在记录'S-1‘之后,有一个很大的时间间隔,然后几秒钟后,其余的立即被记录。时间间隔不应该发生在测井'S-2‘之后吗?

EN

回答 2

Stack Overflow用户

发布于 2022-06-11 21:27:27

允诺构造函数内的函数与脚本的其余部分在同一(而且仅)主线程上同步运行。构建承诺并不会导致创建单独的线程。

如果在允诺构造函数中立即执行一些繁重的处理,则在将控制流返回到允诺构造函数的外部之前,必须完成该繁重的处理。在这种情况下,这意味着循环的多次迭代必须在此之前完成:

  • 构造函数完全完成。
  • 构造函数解析为
  • 这个承诺得到了一个.then处理程序。
  • 最后,console.log("S-2");行运行

为了在不移动日志的情况下获得您想要或期望的输出,您必须将昂贵的代码卸载到不同的环境,例如工人或服务器(使用网络请求)。

票数 3
EN

Stack Overflow用户

发布于 2022-06-11 22:25:24

正如@CertainPerformance所说,Javascript只能处理一个调用堆栈。它需要一劳永逸地完成这个线程。对于承诺和超时,它使用作业和任务队列。事件循环对作业队列进行排序,然后对任务队列进行排序。

让我们试着理解您在调用堆栈和队列方面所写的内容。

代码语言: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.

如果你想让它成为一个回调。

代码语言:javascript
运行
复制
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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72587907

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档