冒着听起来很愚蠢的风险:等待一个承诺解决的最有效方法是什么?说我有承诺A,我想创造承诺B. B的履行不依赖于A的最终价值。即使A被拒绝,也应该继续。然而,该过程不应该开始,直到A以这种或那种方式结算。
我目前的情况如下:
var prevResult;
function doStuff() {
if (prevResult) {
prevResult = promise.settle([ prevResult ]).then(function() {
return doStuff();
})
} else {
prevResult = updateDB().finally(function() {
prevResult = null;
});
}
return prevResult;
}
代码有点不明显。我也有点担心将一堆承诺链接在一起,看看它是如何起到减少琐碎协调的作用。似乎应该有一种更简单的方法。
答案 0 :(得分:3)
最近,.reflect
被引入作为更灵活的.settle
和更好的抽象。您的用例听起来像.reflect
A.reflect().then(function(){
return doSomethingThatReturnsB();
});
代码的完整示例:
var prevResult;
function doStuff() {
prevResult = Promise.resolve(prevResult).reflect().then(function(){
return updateDB();
});
return prevResult;
}
答案 1 :(得分:0)
您可以使用最终,无论先前承诺的结果如何,都会触发。
以下代码来自bluebird github doco。
function ajaxGetAsync(url) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest;
xhr.addEventListener("error", reject);
xhr.addEventListener("load", resolve);
xhr.open("GET", url);
xhr.send(null);
}).finally(function() {
$("#ajax-loader-animation").hide();
});
}
答案 2 :(得分:0)
假设您有两个承诺返回函数doAsync_A
和doAsync_B
。
以下表达式将执行doAsync_A
,等待其承诺结算(成为履行或被拒绝),然后执行doAsync_B
Promise.settle([doAsync_A()]).then(doAsync_B);
doAsync_B
将通过" PromiseInspection"数组(这里是单个元素)。如有必要,您可以测试doAsync_A
是成功还是失败。
function doAsync_B(results) {
var r = results[0];
if (r.isFulfilled()) { // check if was successful
console.log(r.value()); // the promise's return value
} else if (r.isRejected()) { // check if the read failed
console.log(r.reason()); // the promise's rejection reason
}
}
答案 3 :(得分:0)
我认为最好的方法是将doStuff
作为履行和拒绝处理程序:
prevResult = prevResult.then(function() { return doStuff(); },
function() { return doStuff(); });
或者
prevResult = prevResult.catch(ignore).then(function() { return doStuff(); });
您似乎正在尝试排队updateDB
次操作。我建议不要将prevResult
重置为null
,而是将其作为所有排队操作完成后履行的承诺。看看this example。