链条出现故障后是否可以继续?

时间:2013-10-18 15:10:09

标签: promise q

我有类似的东西:

doHTTPRequest()
.then(handleSuccess, checkNotFound)
.then(uploadSomething)
.fail()
.done()

现在当我进入checkNotFound时,我需要检查我是否有404,如果是这样,那不是真正的失败,我想继续使用uploadSomething,但是Q chaining指示我失败。 在任何其他故障(例如:任何其他状态代码)上,我确实想要进入失败()。

2 个答案:

答案 0 :(得分:3)

then的签名是promise.then(onFulfilled, onRejected),它会返回一个新的承诺。返回的promise将通过onFulfilledonRejected返回或抛出来解决。也就是说,如果您处理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()

答案 1 :(得分:0)

如果库与请求对象发生错误,这可能会有效。

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的第二个参数几乎完全是关于promise library interop。在用户代码中,您应该使用通常可用的,更具可读性的.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()
}