Javascript Promise 问题,为什么 Chain 不起作用
Javascript Promise Question, why does Chain not work
所以这行得通
new Promise(res => {
console.log("1")
res(res);
}).then(res => {
console.log("2")
}).then(res => {
console.log("3")
})
但是如果我排除res(res),它就不会链接。但是之后它可以很好地链接而无需任何额外的 res()。
这是为什么,如果第一个块具有 res() 而后续块不需要它以便继续链接,为什么第一个块很重要?
谢谢。
它在不调用 res()
的情况下很好地链接,因为后续的 .then()
处理程序被链接到原始承诺上。
但是,如果您不执行 res(someValue)
,原始承诺将永远不会得到解决,因此,它永远不会调用您的 .then()
处理程序。在某些时候,如果您希望调用任何 .then()
处理程序,则必须在链的开头解决原始承诺。在你调用 res(someValue)
之前,你有一个 promise 链,其中链头处于 pending
状态等待解决或拒绝,因此它可以 运行 链的其余部分.
But if I exclude the res(res), it will not chain. But it chains fine afterwards without any additional res().
必须在第一个 .then()
处理程序被调用之前解决原始承诺。从那时起,只需从 .then()
处理程序 returning 解决链中的下一个承诺 - 您不再需要手动解决它。
在 .then()
处理程序中,您可以通过三种不同的方式触发不同的结果:
Return 来自 .then()
处理程序。 这解决了链式承诺并触发其 .then()
处理程序以获取叫。如果您 return 一个值,该值将成为这部分链的新解析值。如果您没有 return 值或存在隐式 return,则解析值是 undefined
.
从 .then()
处理程序中抛出异常。 这将被 promise 基础结构自动捕获,并将在 promise 中导致此 promise链拒绝 - 触发任何 .catch()
处理程序被调用。
Return 来自 .then()
处理程序的承诺。 这会导致链中的当前承诺跟踪这个新承诺,并且它将根据新 returned promise 的作用解决或拒绝。
此外,给定的承诺只能被解决或拒绝一次。这是一个单向状态机。一旦它被解决或拒绝,它的状态就固定了,不能再改变。因此,您只会调用 res(someValue)
一次。尝试多次调用它只会无济于事,因为承诺已经更改为 fulfilled
状态并且无法再更改。
仅供参考,承诺的三种状态是 pending
、fulfilled
和 rejected
。当您调用 res(someValue)
时,您将链中原始承诺的状态从 pending
更改为 fulfilled
,然后承诺的内部将调用其 .then()
处理程序下一个滴答声。
人们通常没有意识到的是,每次调用 .then()
都会创建并 return 一个链接到早期承诺链的新承诺。因此,您问题中的代码实际上创建了 3 个承诺,一个来自 new Promise()
,两个来自对 .then()
的两次调用。调用 .then()
的这些后续承诺只有在父承诺得到解决或拒绝并且 .then()
或 .catch()
处理程序被调用时才会得到解决或拒绝,然后有一个 return 值来自 .then()
或 .catch()
处理程序。这些处理程序的 return 值决定了链中接下来会发生什么。
所以这行得通
new Promise(res => {
console.log("1")
res(res);
}).then(res => {
console.log("2")
}).then(res => {
console.log("3")
})
但是如果我排除res(res),它就不会链接。但是之后它可以很好地链接而无需任何额外的 res()。
这是为什么,如果第一个块具有 res() 而后续块不需要它以便继续链接,为什么第一个块很重要?
谢谢。
它在不调用 res()
的情况下很好地链接,因为后续的 .then()
处理程序被链接到原始承诺上。
但是,如果您不执行 res(someValue)
,原始承诺将永远不会得到解决,因此,它永远不会调用您的 .then()
处理程序。在某些时候,如果您希望调用任何 .then()
处理程序,则必须在链的开头解决原始承诺。在你调用 res(someValue)
之前,你有一个 promise 链,其中链头处于 pending
状态等待解决或拒绝,因此它可以 运行 链的其余部分.
But if I exclude the res(res), it will not chain. But it chains fine afterwards without any additional res().
必须在第一个 .then()
处理程序被调用之前解决原始承诺。从那时起,只需从 .then()
处理程序 returning 解决链中的下一个承诺 - 您不再需要手动解决它。
在 .then()
处理程序中,您可以通过三种不同的方式触发不同的结果:
Return 来自
.then()
处理程序。 这解决了链式承诺并触发其.then()
处理程序以获取叫。如果您 return 一个值,该值将成为这部分链的新解析值。如果您没有 return 值或存在隐式 return,则解析值是undefined
.从
.then()
处理程序中抛出异常。 这将被 promise 基础结构自动捕获,并将在 promise 中导致此 promise链拒绝 - 触发任何.catch()
处理程序被调用。Return 来自
.then()
处理程序的承诺。 这会导致链中的当前承诺跟踪这个新承诺,并且它将根据新 returned promise 的作用解决或拒绝。
此外,给定的承诺只能被解决或拒绝一次。这是一个单向状态机。一旦它被解决或拒绝,它的状态就固定了,不能再改变。因此,您只会调用 res(someValue)
一次。尝试多次调用它只会无济于事,因为承诺已经更改为 fulfilled
状态并且无法再更改。
仅供参考,承诺的三种状态是 pending
、fulfilled
和 rejected
。当您调用 res(someValue)
时,您将链中原始承诺的状态从 pending
更改为 fulfilled
,然后承诺的内部将调用其 .then()
处理程序下一个滴答声。
人们通常没有意识到的是,每次调用 .then()
都会创建并 return 一个链接到早期承诺链的新承诺。因此,您问题中的代码实际上创建了 3 个承诺,一个来自 new Promise()
,两个来自对 .then()
的两次调用。调用 .then()
的这些后续承诺只有在父承诺得到解决或拒绝并且 .then()
或 .catch()
处理程序被调用时才会得到解决或拒绝,然后有一个 return 值来自 .then()
或 .catch()
处理程序。这些处理程序的 return 值决定了链中接下来会发生什么。