Node.js 蓝知更鸟:等待一个承诺

Node.js 蓝知更鸟:等待一个承诺,node.js,promise,bluebird,Node.js,Promise,Bluebird,冒着听起来愚蠢的风险:等待一个承诺兑现的最有效方式是什么?假设我有承诺A,我想创建承诺B。B的实现不取决于A的最终值。即使A被拒绝,它也应该继续。然而,这个过程不应该开始,直到以某种方式解决了一个问题 我目前的情况如下所示: var prevResult; function doStuff() { if (prevResult) { prevResult = promise.settle([ prevResult ]).then(function() {

冒着听起来愚蠢的风险:等待一个承诺兑现的最有效方式是什么?假设我有承诺A,我想创建承诺B。B的实现不取决于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;
}

代码有点不明显。我也有点担心将来自solite()的一系列承诺链接在一起,看看它是如何执行不那么琐碎的协调的。似乎应该有一种更简单的方法来实现这一点。

您可以使用finally,它会激发,而不管前面承诺的结果如何

以下代码来自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();
    });
}

假设您有两个承诺返回函数
doAsync_A
doAsync_B

下面的表达式将执行
doAsync\u A
,等待其承诺解决(履行或拒绝),然后执行
doAsync\u B

Promise.settle([doAsync_A()]).then(doAsync_B);
doAsync\u B
将传递一个“PromiseInspection”数组(此处为单个元素)。如有必要,您可以测试
doAsync\u 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
    }
}

根据

改编,我认为最好的方法是将doStuff作为履行和拒绝处理程序:

prevResult = prevResult.then(function() { return doStuff(); },
                             function() { return doStuff(); });
或者

prevResult = prevResult.catch(ignore).then(function() { return doStuff(); });


似乎您正在尝试对
updateDB
操作排队。我建议不要将
prevResult
重置为
null
,而是在完成所有排队操作后,将其作为一个承诺。看看。

最近,
.reflect
作为一种更灵活的
.solite
和更好的抽象概念被引入。您的用例听起来很容易使用
。reflect

A.reflect().then(function(){
   return doSomethingThatReturnsB();
});
代码的完整示例:

var prevResult;
function doStuff() {
    prevResult = Promise.resolve(prevResult).reflect().then(function(){
        return updateDB();
    });
    return prevResult;
}

“你的意思是你想要有两个承诺,即使承诺A被拒绝,你也会忽略它,想要继续吗?”thefourtheye。对生成A和B的操作是独立的。它们不能同时发生。是的,您的代码非常不明显,尤其是
prevResult=null
这件事。这到底是干什么用的?什么是
doStuff
?将
prevResult
设置为空,允许继续下一个操作。如果我设置条件
prevResult&&,我想代码会更明显一些!prevResult.isCompleted())
并删除finally()。这意味着实现值不会得到gc'ed。finally()返回一个承诺,该承诺生成调用它的承诺的值(而不是回调的返回值)。为什么使用匿名包装器?为什么不干脆
。那么(doStuff,doStuff)
?@jfriend00:取决于您是否希望任何参数指向
doStuff
。如果你不在乎,那么
。那么(doStuff,doStuff)
肯定更好。
。reflect
似乎获得了一些动力。我会发现
.inspectify
更直观。你知道我在这里使用“反射”的麻烦在于它是比喻性的。从字面上讲,反射是在镜子中发生的事情,或是作为一个整体。我唯一记得佩特卡安东诺夫用法的方法是“反思”==“检查”:放松也意味着审视自己感谢你的回答。但我认为第二个例子并不正确。