首页 > 解决方案 > Promise `.then`、`.catch` 和 `.finally` 如何以及何时进入 EventLoop 微任务队列?

问题描述

.then,.catch.finally在注册后立即进入 JS 事件循环(当 JS 运行时解释适当的代码时)或以某种方式不同?

这个问题的理论较少如下:

我有以下代码(链接到JSBin(在线 JS 执行环境)

l = console.log

const g = (title) => {
    return (a) => {
      l(title + a)
      return a+1;
    }
};

const gA = g("A ")
const gB = g("B ")

const throwError = (title) => {
    return (a) => {
      l(title + a)
      throw new Error("Error from promise " + title + a)
    }
}; 

promise = new Promise((resolve, reject) => {
  resolve(1)
})

l("Started application")

promise
  .then(gA)
  .then(gA)
  .then(throwError("A "))
  .catch(err => {
    l(err.message);
  })


promise
  .then(throwError("B "))
  .then(gB)
  .then(gB)
  .catch(err => {
    l(err.message);
  })

l("Finish main function")

解析为控制台中的以下输出

"Started application"
"Finish main function"
"A 1"
"B 1"
"A 2"
"A 3"
"Error from promise A 3"
"Error from promise B 1"

如果承诺回调按照注册的顺序执行,我希望"Error from promise B 1"这个输出更高。但他们最终出现了。为什么会这样?

标签: javascriptes6-promise

解决方案


.then注册后立即进入 JS 事件循环,还是以某种方式.catch不同?.finally

这些承诺方法本身永远不会出现在队列中。任务队列包含承诺反应,基本上说“在承诺 Z 的结果上运行回调 X/Y”。(而且它们总是成对的then回调,因为这就是catch内部finally使用的内容)。

then这些 Promise 反应在 Promise 确定后立即安排,或者在 Promise 已经确定时立即安排在调用期间。

如果 Promise 回调按照注册的顺序执行

他们是。但这仅适用于每个 promise。在您的代码中,您要附加多个回调的唯一承诺是promise,并且gA 运行时间早于throwError("B "). 不能保证附加到不同承诺的回调,因为这些承诺无论如何都会在不同的时间解决。


推荐阅读