我想承诺一个承诺,就像这样:
let first = new Promise(resolveFirst => {
setTimeout(() => {
resolveFirst("resolved!");
}, 2000)
});
let second = new Promise(resolveSecond => {
setTimeout(() => {
resolveSecond(first);
}, 10)
});
second.then(secondValue => {
console.log("second value: ", secondValue);
secondValue.then(firstValue => {
console.log("first value: ", firstValue);
});
});
这样console.log("second value: ", secondValue);
在10
毫秒后打印,然后console.log("first value: ", firstValue)
将被打印2000
。
虽然我得到了:
第二个值:已解决!
错误:
未捕获(承诺)TypeError:secondValue.then不是函数
在2010
毫秒之后一起。
似乎当第二个承诺得到解决,并且第一个承诺被返回时,它会自动等待第一个承诺解决。
为什么?我怎么在他们之间打破?
以下是使用Array.reduce()
在Facebook上发布的解决方案:
const runPromisesInSeries =
ps => ps.reduce((p, next) =>
p.then(next), Promise.resolve());
const delay = d => new Promise(r => setTimeout(r, d));
runPromisesInSeries([() => delay(1000), () => delay(2000)]);
//executes each promise sequentially, taking a total of 3 seconds to complete
答案 0 :(得分:3)
按照设计,在第二个承诺得到解决(履行或拒绝)后,以第二个承诺解决的承诺将承担第二个承诺的价值和状态,等待必要时将其结算。
除非promise库存在严重缺陷,否则不可能使用promise或者thenable对象(具有then
method`)值的任何对象来履行承诺(旧版本的JQuery将使用它们自己的promise对象)来自不同图书馆的承诺对象。)
承诺拒绝没有相同的检查,并且很乐意将承诺对象传递到链中而不等待它被解决。所以你可以用第一个承诺拒绝第二个承诺并在catch
子句中选择它。
虽然技术上可行但我强烈建议不要这样做,除非证明可以这样做 - 这对于试图理解代码的第三方来说是一个维护问题。
虽然您可以将承诺作为对象属性传递到承诺链的成功渠道,但对承诺组合的重新分析可以提供更好或更标准的解决方案。例如。在继续执行共同任务之前,Promise.all
等待两个或更多独立承诺得以履行。
答案 1 :(得分:1)
这只是他们魅力的一部分:如果你的承诺A解析为一个可靠的B,那么只有在B结算后A才会解决,而A会获得B的解析值。这是Promises/A+和ES6的一部分,是“承诺解决程序”的一部分。
如果(比方说)一个动作在完成之前需要一个动作(比如登录),或者需要加载另一个结果页面,或者有自己的重试逻辑,你可以看到一些优点。
虽然它不是非常惯用,但是如果你想立即返回一个未解决的承诺而不等待它,你可以通过{object}
或[array]
传递它,但可能没有多少原因是:除了等待完成之外,你会对退回的承诺做些什么?
答案 2 :(得分:0)
您只能将then
链接到承诺。
secondValue
不是承诺,它只是您调用second
承诺时返回的值。或该承诺的resolved
值。
如果您希望这样做,请尝试以下方法:
let first = new Promise(resolveFirst => {
setTimeout(() => {
resolveFirst("resolved!");
}, 2000)
});
let second = new Promise(resolveSecond => {
setTimeout(() => {
resolveSecond(first);
}, 10)
});
second.then(secondValue => {
console.log("second value: ", secondValue);
/** first is a Promise. return a promise, and the next "then"
* will pass the result of that Promise.
*/
return first
})
.then(firstValue => {
console.log(firstValue)
})
进一步解释为什么second
承诺解决了string
承诺的最终价值(first
),而不是承诺本身,can be found on mdn:
<强> Promise.resolve()强>
如果值是promise,则该对象成为对Promise.resolve的调用的结果;否则返回的承诺将用值来实现。