使用Q.promises:如何捕获异步抛出的错误?

3
我正在使用Q来处理Promise,但在设置一些测试时,我发现无法捕获返回Promise的函数中抛出的异步错误。
我尝试使用Q.when包装它,并链接一个fail或者像下面这样,使用Q.fcall和链接的fail,但是我无法让它正常工作。
    var func = function(){

               var deferred = Q.defer(); 
               setTimeout(function(){
                    throw new Error("async error");
               },100);

               return deferred.promise;

            }

            Q.fcall(func)
            .then(function(){
                console.log("success"); 
            })
            .fail(function(err){
                console.log(err); 
            })

有没有方法可以做到这一点?

1个回答

2

setTimeout中的异常与Promise无关,您需要使用try-catch块自行捕获异常。

或者您可以使用Q.delay

function func(){
    return Q.delay(100).then(function(){
        throw new Error("async error");
    });
}

func()
.then(console.log.bind(console, "success"))
.fail(console.log.bind(console));

我明白这一点。问题是,通过 Q 执行的这些函数可能是在我无法控制的情况下开发的,因此我不能依赖于正确的 try/catch。现在,我考虑选择在周围的 Promise 中添加一个计时器,以至少能够在超时后进行拒绝并在我的框架中进行正确的异常处理。希望有更简洁的方法。 - Geert-Jan
1
Q.timeout可以解决这个问题。如果那些第三方函数抛出错误到无处,你真的无能为力(或者尝试使用window.onerror构建一些东西)。 - Bergi
Geert-Jan,你只需要使用返回承诺(点)的异步函数即可。这是一个简单且可接受的规则。试图黑客式地修改本机函数以使setTimeout返回承诺,将会给你带来更多麻烦而不是帮助。 - Mariusz Nowak
@Bergi 我已经创建了一个gist,其中包含您提出的解决方案,但是当我运行它时,它总是在控制台日志中打印“success”。 https://gist.github.com/pulakb/e9be0e273e8f7c2d92b6 - Pulak Kanti Bhattacharyya
1
@PulakKantiBhattacharyya:当函数返回一个Promise时,您不需要使用fcall(并且在没有回调函数时不能使用它)。我已经更新了代码示例以展示它应该如何使用。 - Bergi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接