我一直在试图弄清楚这个问题,我想知道分辨率值是如何传递的,getAnswer
then
调用。首先,我return
add
的结果,我认为它返回了一个 Promise,它允许我在getAnswer
上对then
方法使用then
调用,但是第二个return
语句是如何传递给它的?
function add(num1, num2) {
return new Promise((resolve, reject) => {
setTimeout(() => {resolve(num1 + num2);}, 500)
});
}
function getAnswer() {
return add(5, 5).then((res) => {
console.log(res);
return new Promise((resolve, reject) => {
resolve("How does this get passed too getAnswer's then function?");
});
});
}
getAnswer().then((res) => {
console.log(res);
})
基础知识:
add
返回一个 Promise,它是Promise
对象的一个实例,Promise
的每个实例都有一个then
方法,您可以使用该方法来观察该 promise 的解析。
出于链接目的,then
被设计成它返回一个 Promise 本身(因此,JavaScript 中的每个then
调用将始终返回一个新的 promise)。then
返回的承诺将使用其处理程序的返回值进行解析(稍后会详细介绍)。
现在,当你说:
return add(5, 5).then((res) => {
console.log(res);
return new Promise((resolve, reject) => {
resolve("How does this get passed too getAnswer's then function?");
});
});
您不会返回add
的结果,而是返回通过对add
的结果调用then
来创建的承诺(这只是标准的 JS 行为)。
您的问题:
但是,第二个返回语句是如何传递给它的呢?
根据 MDN,以下是then
方法返回的内容(([])
里面的部分是我的补充):
处于待处理状态的承诺([这是您的第一个
返回return
语句实际返回的内容])。然后异步调用处理程序函数(onFulfilled 或 onRejected)([示例中的处理程序是您在getAnswer
中传递给then
的函数])。调用处理程序函数后,如果处理程序函数:
- 一个值,然后返回的承诺以返回的值作为其值进行解析;
- 抛出错误,然后返回的承诺被拒绝,抛出的错误作为其值;
- ([这是你的情况 - 你的第二个
返回return
])返回一个已经解决的承诺,然后返回的承诺以该承诺的值作为其值进行解析;- 已拒绝的承诺,然后返回的承诺被拒绝,该承诺的值作为其值。
返回- 另一个挂起的承诺对象,届时返回的承诺的解析/拒绝将在处理程序返回的承诺的解决/拒绝之后。此外,届时返回的承诺值将与处理程序返回的承诺值相同。
就我个人而言,每当我看到then
的处理者返回承诺时,我只是假设 - 为了简化我的想法 - 最初由then
返回的承诺已被then
的处理者刚刚返回的承诺所取代。当然,这种心理映射与实际功能AFAIK是平行的。
所以,总结一下:
getAnswer
返回一个承诺——由add(5, 5).then(...)
创造。- 然后,你观察到返回的承诺使用
then
(getAnswer().then(...)
)--这里无关,但这个调用也创建了一个承诺。 - 碰巧用于观察
add
调用返回的承诺的处理程序(此处理程序是您在 #1 中传递给then
的函数)也返回一个承诺,规则是,如果then
的处理程序返回一个承诺p
,那么每当p
用值v
解析时, 最初的承诺 - 由then
创造 - 也将通过v
解决。 - 最后,您传递给 #2 中的
then
以观察getAnswer()
返回的承诺的处理程序将使用 #3 中v
的值进行调用。
请随时要求任何澄清,但在此之前,请仔细阅读本文。