【问题标题】:How is a Promise That Is Returned From A Resolve Handler Mapped To The Return Value of 'then'?从 Resolve 处理程序返回的 Promise 如何映射到 'then' 的返回值?
【发布时间】:2017-01-22 20:31:51
【问题描述】:

如果我正在链接 Promise 并从解析处理程序返回一个 Promise,那么该 Promise 如何成为对 then 的调用的返回值?幕后发生了什么?

在下面的示例中,在firstMethodHandler 中,对secondMethod 的调用会收到一个新的Promise,然后它会返回该Promise,但该Promise 会从then 方法中返回,并在该方法中将它传递给它的Promise。这是怎么发生的?

function firstMethod(value) {
  console.log('1st method:', value)
  return new Promise((resolve, reject) => {
    resolve(++value);
  });
}

function secondMethod(value) {
  return new Promise((resolve, reject) => {
    console.log('2nd method:', value)
    resolve(++value);
  });
}

function firstMethodHandler(value) {
  console.log("1st method handler:",value);
  return secondMethod(value);
}

function secondMethodHandler(value) {
  console.log("2nd method handler:", value);
}


firstMethod(1)
  .then(firstMethodHandler)
  .then(secondMethodHandler)

【问题讨论】:

标签: javascript ecmascript-6 es6-promise


【解决方案1】:

这里的关键是p1.then() 返回一个新的承诺,我们将称之为p2。当p1 被解析时,它会调用附加到它的.then() 处理程序。当您从该.then()(我们将其称为p3)返回另一个承诺时,p3 将链接到p2,因此p2p3 解决之前不会被解决。因此,原始p1.then() 的调用者将返回一个承诺p2,直到p1p3 都解决后才会解决。事情就是这样被链接在一起的。

通常,这里的关键信息是 p1.then() 返回一个新的 Promise,并且该 Promise 会受到前一个 .then() 处理程序中发生的事情的影响。

你可以在这里看到类似的解释:

Difference between resolve and return in promise JS


在您的具体示例中:

firstMethod(1)
  .then(firstMethodHandler)
  .then(secondMethodHandler)

firstMethod() 返回一个我将调用p1 的承诺。然后,对该 promise 调用 .then(firstMethodHandler) 会返回一个新的 promise p2,然后调用 .then(secondMethodHandler) 会创建一个新的 promise p3

在未来的某个时候,firstMethod() 会解析它返回的承诺。所以,现在p1 已解决。这会调用附加到它的.then() 处理程序,从而调用firstMethodHandler()。这将返回一个新的承诺p4。将p4 链接到p2 承诺,所以p2 直到p4 才会解决。在未来的某个时间点,p4 解析允许p2 解析。这会调用附加到p2.then() 处理程序,从而调用secondMethodHandler(),您会看到最终的console.log()

从解释中可以看出,这里的关键是p2p3 第一次执行.then() 时创建的新promise。这就是链接的.then() 处理程序实际链接到的内容,这些承诺受附加的.then() 处理程序返回的内容的影响。

要查看链接在做什么,我们可以删除实际的链接并向您展示自动创建和使用的实际中间变量:

var p1 = firstMethod(1);
var p2 = p1.then(firstMethodHandler);
var p3 = p2.then(secondMethodHandler);

p1 在内部解析为 firstMethod() p2p1.then(...) 的返回值 p3p2.then(...)的返回值

当调用firstMethodHandler 时(在p1 解析之后),它返回链接到p2p4,因此p2 直到p4 解析后才会解析。当p4 最终解析时,它允许p2 解析,然后调用secondMethodHandler。当 .then() 处理程序返回正常值时,p3 被解析,整个链完成。

【讨论】:

  • 你说'当你从那个 .then() 返回另一个承诺时',但这正是我的问题。我没有从 then() 中返回一个承诺。我从传递给 then() 的函数/处理程序中返回它。这个承诺最终是如何从 then() 中返回的?我对那个机制很感兴趣。
  • @Pedr - 每次调用 .then() 都会返回一个新的承诺。 .then() 的返回值是一个新的承诺。那不是你做的事情。这就是.then() 的工作原理。请记住,链上所有对 .then() 的调用都会立即执行,并且它们的 Promise 会立即创建。传递给.then() 的回调在内部注册为事件处理程序,以便以后可以调用它们。请阅读我回答的最后四段。这向您展示了自动为您创建的所有中间承诺。
  • 谢谢。我认为一分钱刚刚下降。我知道我从回调中返回的承诺与对then() 的调用返回的承诺相同,但当然这是不可能的,因为then() 已经返回。我会挑选你的答案,并希望我能上床睡觉。
  • @Pedr - 是的,promise 是链接在一起的,因此在链中解析一个会导致原始返回到链上很远的那个最终得到解决,这就是调用者实际看到的。这有点令人困惑。最终,您将了解链式概念的工作原理,并且可以直接使用它,而不必费力去弄清楚链式的实际实现方式。
猜你喜欢
  • 1970-01-01
  • 2020-04-16
  • 1970-01-01
  • 1970-01-01
  • 2018-11-16
  • 2021-03-17
  • 2021-08-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多