我有类似的东西:
doHTTPRequest()
.then(handleSuccess, checkNotFound)
.then(uploadSomething)
.fail()
.done()
现在,当我进入 checkNotFound 时,我需要检查我是否得到 404,如果是,这不是真正的失败,我想继续 uploadSomething,但 Q 链接指示我失败。在任何其他失败(例如:任何其他状态代码)上,我确实想进入失败()。
then
is的签名,promise.then(onFulfilled, onRejected)
它返回一个新的承诺。返回的承诺由任何onFulfilled
或onRejected
返回或抛出来解决。也就是说,如果您处理错误onRejected
并返回一个履行的承诺,它将传递给结果并跳过您的fail
处理程序。在代码中:
function request(url) {
// returns a promise
}
function retryForeverLoop(url) {
return request(url).then(null, function (error) {
return retryForeverLoop(url);
});
// note that retrying forever might not work out well
}
retryForeverLoop(url)
.then(uploadSomething)
.done()
如果库错误返回请求对象,这可能会起作用。
doHTTPRequest()
.fail(function(request){
if( request.isRequest && request.is404 ) {
//This will propagate to the next .then
return request;
}
else {
//This will propagate to the next .fail
throw request;
}
})
.then(handleSuccess)
.then(uploadSomething)
.fail()
.done()
顺便说一句,第二个论点.then
几乎完全是关于承诺库互操作的。在用户代码中,您应该使用通常可用、可读性更高.catch/.fail/.whatever
的替代方案,这也避免了这里提到的陷阱https://github.com/kriskowal/q/#handling-errors。如果这样的替代方法不可用,即使那样,也.then(null, handler)
应该使用而不是在同一个.then
调用中传递错误和成功。
上述代码的同步等价物如下:
try {
try {
var a = doHTTPRequest();
}
catch(request) {
if( request.isRequest && request.is404 ) {
a = request;
}
else {
throw request;
}
}
uploadSomething(handleSuccess(a));
}
catch( e ) {
//This is the second .fail()
}