1

我有类似的东西:

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

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

4

2 回答 2

3

thenis的签名,promise.then(onFulfilled, onRejected)它返回一个新的承诺。返回的承诺由任何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()
于 2013-10-19T01:07:50.740 回答
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几乎完全是关于承诺库互操作的。在用户代码中,您应该使用通常可用、可读性更高.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()
}
于 2013-10-19T13:36:52.443 回答