有没有一种短路Javascript承诺的好方法?

qix*_*qix 5 javascript promise jquery-deferred

承诺/延期我是一个新手.对于成功和错误案例,是否有一个好的模式来处理人们可能希望短路承诺链的情况?在错误的情况下,我知道你可以链接.then(null, function(error) {})到最后并从任何先前的域中捕获错误,但是如果你想以更自定义的方式处理错误并终止怎么办?您是否会在先前的错误处理程序中指定错误的"类型"并通过新的承诺返回它,以便在最终的错误处理程序中处理或跳过?那么一个成功案例,你想要在链中更早地终止(只是有条件地解雇任何后来then的)?

jor*_*aul 4

通常,承诺链从调用某个异步函数开始,如下所示:

var promise = callAsync();
Run Code Online (Sandbox Code Playgroud)

如果您要链接第二个异步调用,您可能会执行以下操作:

var promise = callAsync()
.then(function(){
    return callOtherAsync();
})
.then(function(){
    return callSuccessAsync();
}, function(){
    return callFailAsync();
});
Run Code Online (Sandbox Code Playgroud)

作为链接的结果,promisenow 包含最终的 Promise,当callFinalAsync()的 Promise 完成时,该 Promise 也完成。使用此模式时,无法短路 Final promise- 您可以一路返回失败的 Promise(例如,而不是返回 callOtherAsync 的结果),但这需要失败的 Promise 在链中前进(从而导致 callFailAsync被称为)。您始终可以在回调中完成或拒绝promise来自这样的回调

var promise = callAsync()
.then(function(){
    if(fail){
        promise.reject();
        //no way to halt progression 
    }else{
        return callOtherAsync();
    }
})
.then(function(){
    return callSuccessAsync();
}, function(){
    return callFailAsync();
});
Run Code Online (Sandbox Code Playgroud)

但是,这不会阻止对 的调用callFailAsync()。一些 Promise/A 实现公开了stop专门用于此目的的方法。通过停止,你可以这样做:

var promise = callAsync();
.then(function(){
    if(fail){
        this.stop(); 
        promise.reject();
    }else{
        return callOtherAsync();
    }
})
.then(function(){
    return callSuccessAsync();
}, function(){
    return callFailAsync();
});
Run Code Online (Sandbox Code Playgroud)

这取决于能否访问中间承诺this。一些 Promise 实现禁止这样做(强制this为 window/null/etc),但您可以通过闭包来处理它。

TL;DR:Promise/A 规范没有提供链短路功能,但添加一个并不难。