有没有一种很好的方法来缩短Javascript承诺?
我是一个有点信誓旦旦的新手。有没有一个好的模式来处理这样的情况:一个人可能想要缩短一系列承诺的时间,不管是成功还是失败?在错误情况下,我知道您可以将有没有一种很好的方法来缩短Javascript承诺?,javascript,promise,jquery-deferred,Javascript,Promise,Jquery Deferred,我是一个有点信誓旦旦的新手。有没有一个好的模式来处理这样的情况:一个人可能想要缩短一系列承诺的时间,不管是成功还是失败?在错误情况下,我知道您可以将.then(null,function(error){})链接到末尾,并从前面的任何then中捕获错误,但是如果您希望以更自定义的方式处理错误并终止,该怎么办?您会在早期的错误处理程序中指定错误的“类型”,并通过新的承诺返回它,以便在最终的错误处理程序中处理或跳过它吗?如果您希望在链中提前终止(仅有条件地触发任何后续的然后),那么成功案例又如何呢?通
.then(null,function(error){})
链接到末尾,并从前面的任何then中捕获错误,但是如果您希望以更自定义的方式处理错误并终止,该怎么办?您会在早期的错误处理程序中指定错误的“类型”,并通过新的承诺返回它,以便在最终的错误处理程序中处理或跳过它吗?如果您希望在链中提前终止(仅有条件地触发任何后续的然后),那么成功案例又如何呢?通常,承诺链从调用某个异步函数开始,例如:
var promise = callAsync();
如果要链接第二个异步调用,可能会执行以下操作:
var promise = callAsync()
.then(function(){
return callOtherAsync();
})
.then(function(){
return callSuccessAsync();
}, function(){
return callFailAsync();
});
作为链接的结果,promise
现在包含最终承诺,当callFinalAsync()
的承诺完成时,最终承诺完成。使用此模式时,没有办法缩短最终的承诺
——您可以一路返回失败的承诺(例如,而不是返回callOtherAsync的结果),但这需要失败的承诺在整个链中进行(从而导致调用callFailAsync)。
您始终可以在回调中履行或拒绝承诺
var promise = callAsync()
.then(function(){
if(fail){
promise.reject();
//no way to halt progression
}else{
return callOtherAsync();
}
})
.then(function(){
return callSuccessAsync();
}, function(){
return callFailAsync();
});
但是,这不会阻止调用callFailAsync()
。一些Promise/A实现为此目的公开了一个stop
方法。使用stop,您可以执行以下操作:
var promise = callAsync();
.then(function(){
if(fail){
this.stop();
promise.reject();
}else{
return callOtherAsync();
}
})
.then(function(){
return callSuccessAsync();
}, function(){
return callFailAsync();
});
这取决于使用this
访问中间承诺。一些Promise实现禁止这样做(强制将this
设置为window/null/etc),但您可以通过闭包来处理这个问题
TL;DR:Promise/A spec不提供链短路功能,但添加一个并不困难。不确定jQuery,但至少在任何Promise/A+中,您可以抛出:
.then(function() {
if (skip) {
throw new Error("skipping");
}
})
//Chain of thens
.then(...)
.then(...)
.then(...)
.then(...)
.catch(function(){
//skipped here
});
我假设您的用例如下所示:
promise
.then(a)
.then(b); // We want to have an option to break here
.then(c)
.done(d)
处理这一问题的逻辑方法是:
promise
.then(a)
.then(function (result) {
if (something) throw new Error("Do not proceed!");
return b(result).then(c).then(d);
}).done();
如果您不喜欢嵌套,可以将b(result).然后(c).然后(d)
组合为外部函数。我在应用程序中遇到了这个问题,通过使用一个简单的取消令牌对象实现了短路/取消,该对象可以在Promise的异常/拒绝处理程序回调中检查。也许不是最优雅的解决方案,但在不需要额外的库或替代/非标准的Promise实现的情况下,似乎工作得足够好
const cancellationToken = {};
somePromiseReturningMethod(...)
.then(doSomething)
.then(doSomethingElse)
.catch(err => {
if (err === cancellationToken)
{
// handle cancellation here and return
}
// handle "regular" errors here (show/log a message, etc)
});
function doSomething(dataFromPromise)
{
// check for whatever condition should result in cancellation/short-circuit
if (...)
{
return Promise.reject(cancellationToken);
}
// carry on as normal...
}
method.success(函数(){}).error(函数(){})
?