【问题标题】:setTimeout performing before a task in micro task queue (Job queue)setTimeout 在微任务队列(作业队列)中的任务之前执行
【发布时间】:2019-07-12 09:27:09
【问题描述】:

我无法理解为什么下面的代码会按顺序记录以下内容: “结尾” “超时完成” “承诺”

我假设“承诺”会在“超时完成”之前记录,因为它的优先级高于回调队列任务 (setTimeout)。 在此观察后我的假设是,在调用 .then 之前,promise 不会将其任务排入队列,因为它还没有准备好,因此允许 setTimeout 在回调队列中首先执行。这是正确的吗?

const sampleFunction = function(e) {
  setTimeout(() => console.log('timeout done'), 0)
  const data = fetch(`https://jsonplaceholder.typicode.com/comments/1`)
  .then(response => {
    return response.json();
  })
  .then(json => {
    /*doSomething*/
    console.log('promise')
  });
  console.log('end')
}

【问题讨论】:

  • 一个已经解析的promise优先于回调队列,但是你的promise直到网络请求完成后才会解析。

标签: javascript asynchronous callback es6-promise ecmascript-2016


【解决方案1】:

您的console.log('promise') 必须等到您的fetch().then() 完成,这涉及到另一台主机的网络操作(因此非零时间)。

您的setTimeout() 只需等到sampleFunction() 返回并返回事件队列。因此,由于fetch().then() 是非阻塞的并且占用非零时间,当您第一次返回事件队列时,只有setTimeout() 准备就绪。联网操作仍将在后台进行。

因此,这不是优先级问题。这是完成顺序的问题。 setTimeout() 在解决 fetch() 承诺之前很久就将其完成事件插入到事件队列中。

也许您没有意识到fetch() 是非阻塞的,调用它只是启动操作,然后您的代码继续执行?

在控制台中,您应该看到:

end
timeout done
promise

只要您的fetch() 没有任何错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-19
    • 1970-01-01
    • 2019-02-14
    • 1970-01-01
    • 2017-07-18
    • 2017-11-12
    • 1970-01-01
    相关资源
    最近更新 更多