如何从一个解决处理程序返回的答案映射到'那么'?

时间:2017-01-22 20:31:52

标签: javascript ecmascript-6 es6-promise

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

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

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)

1 个答案:

答案 0 :(得分:1)

这里的关键是p1.then()返回我们称之为p2的新承诺。解析p1后,会调用附加到它的.then()处理程序。当您从.then()(我们将其称为p3)返回另一个承诺时,p3会被链接到p2,因此p2将无法解决p3结算。因此,原始p1.then()的来电者将获得一个承诺p2,在p1p3被解析之前,该承诺将无法解决。这就是事物链接在一起的方式。

通常,这里的关键信息是p1.then()返回一个新的承诺,而这个承诺受到前一个.then()处理程序内部发生的事件的影响。

您可以在此处看到类似的解释:

Difference between resolve and return in promise JS

在您的具体示例中:

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

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

在将来的某个时刻,firstMethod()会解决它返回的承诺。所以,现在p1已经解决了。这会调用附加到它的.then()处理程序,从而调用firstMethodHandler()。这会返回一个新的承诺p4。这会将p4链接到p2承诺,因此p2只有p4才会解决。在将来的某个时刻,p4会解析,允许p2解决。这会调用附加到.then()的{​​{1}}处理程序,从而调用p2,您会看到最终的secondMethodHandler()

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

要查看链接的作用,我们可以删除实际的链接并显示自动创建和使用的实际中间变量:

.then()

var p1 = firstMethod(1); var p2 = p1.then(firstMethodHandler); var p3 = p2.then(secondMethodHandler); 已在p1内部解析 firstMethod()p2的返回值 p1.then(...)p3

的返回值

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