【问题标题】:calling setTimeout before Promise [duplicate]在 Promise 之前调用 setTimeout [重复]
【发布时间】:2021-09-17 18:27:46
【问题描述】:

代码片段:

console.log('out1');
setTimeout(() => console.log('out2'), 0);
Promise.resolve('out3').then(console.log);
console.log('out4');

执行后我得到以下信息:

"out1"
"out4"
"out3"
"out2"

根据我的理解,由于第 2 行和第 3 行都是异步的,所以 out2 应该先打印,因为它首先放入队列。 但这里似乎相反。

"out1"
"out4"
"out2"
"out3"
  1. 谁能解释一下我在这里遗漏了什么。
  2. 代码中的第 3 行仅通过传递一个 console.log 是如何工作的

JSBin 链接:https://jsbin.com/fafipezine/edit?js,console

【问题讨论】:

  • “根据我的理解...” - 请添加您认为会发生的情况,以便我们实际回答 1。
  • “第 3 行如何...” - 这只是一个回调。 .then() 需要一个将被执行的函数。你通过它console.log
  • 你可以这样写:Promise.resolve('out3').then(x => console.log(x)); 但该函数只是将它的参数传递给 console.log,所以你可以只传递 console.log 函数本身。
  • 至于1.,这里是JS event loop。您的问题似乎是为什么 Promise 在零延迟超时之前解决?为什么你期望超时首先解决?即使是零延迟超时也会在事件循环中“稍后”排队和处理,它只会在下一个可能的时刻轮到它。但显然是在承诺之后。
  • @Andreas 你现在可以检查一下吗。

标签: javascript promise timeout


【解决方案1】:

要回答您的问题,我们需要阐明 javascript 如何执行代码。 Javascript 遵循run to completion model,这几乎意味着您的代码无论如何都会到达 out4 控制台日志(如果您在代码中使用 async await 或发生同步错误等情况除外) Javascript 使用单线程模型,那么它是如何处理代码执行的呢? 专注于你的第一个问题,我们需要看看任务队列和微任务队列是如何运作的。 这些队列基本上是在为事件循环提供要做的事情。那么,它们以什么顺序被消耗呢?事件循环通过首先执行当前任务来消耗消息,然后继续执行可能引入的所有微任务等等(check the tasks vs microtasks topic)。 那么,什么是任务,什么是微任务呢? 每次请求代码运行、调用 setTimeout 或 setInterval 或触发事件(例如用户输入事件)时,都会创建一个 task microtask 与任务非常相似,但它们的创建方式不同。 Promises are basically using microtasks

要回答您问题的第一部分,有两个任务。第一个任务是运行这个脚本。入队的第二个任务是触发 setTimeout 的回调。在这两个任务之间,有两个 Promises(微任务)排队。以上所有的结果都是你看到的打印顺序。 this 博客文章中对上述内容进行了很好的可视化,我强烈建议您阅读。

根据您的第二个问题,then function 可以使用函数引用作为参数

【讨论】:

    【解决方案2】:

    您可以通过在 setTimeout 函数中解析 promise 来实现:

    console.log('out1');
    
    new Promise((res) => {
      setTimeout(() => {
        console.log('out2');
        res("out3");
      }, 0);
    }).then(console.log);
    
    console.log('out4');
    

    您可以阅读有关这些行为的 Javascript 中的 EventLoop。

    【讨论】:

    • 感谢您的回答,但这并不是我想要的。只需要背后的详细推理。
    猜你喜欢
    • 1970-01-01
    • 2020-07-13
    • 2021-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-28
    • 2017-09-24
    • 2020-10-25
    相关资源
    最近更新 更多