繁体   English   中英

Angular - 在promise链的第一个函数中处理$ q中的异常

[英]Angular - Handling exceptions in $q in the first function of a promise chain

请考虑以下代码:

// Fiddle - http://jsfiddle.net/EFpn8/3/
f1().then(function(data) {
                console.log("success 1: "+data)
                return f2();
            })
            .then(function(data) {console.log("success 2: "+data)})
            .catch(function(data) {console.log("error: "+data)});

function f1() {
    var deferred = $q.defer();
    // An exception thrown here is not caught in catch
    // throw "err";
    deferred.resolve("done f1");        
    return deferred.promise;
}

function f2() {
    var deferred = $q.defer();
    // An exception thrown here is handled properly
    // throw "err";
    deferred.resolve("done f2");        
    return deferred.promise;
}    

如果以下代码在f2中运行异常,则正确调用catch函数。 但是,如果f1中存在异常,则catch代码永远不会执行,只会发生标准的JS异常。

在原始Q库中,这可以通过以下代码处理:

    // Fiddle - http://jsfiddle.net/FEPc7/
    Q.fcall(f1).then(function(data) {
        console.log("success 1: "+data)
        return f2();
    })
    .then(function(data) {console.log("success 2: "+data)})
    .catch(function(data) {console.log("error: "+data)});

使用fcall可以安全地保护f1函数,并且其中的异常将按预期触发catch函数。

由于似乎承诺链的所有成员的相同行为对开发人员来说是有用和自然的,因此我为AngularJS创建了以下函数:

// Fiddle - http://jsfiddle.net/EFpn8/5/
function promise(work) {
    var deferred = $q.defer();
    try {
        deferred.resolve(work());
    } catch(err) {
        deferred.reject(err);
        throw err;
    }
    return deferred.promise;        
}

哪个可以这样使用:

promise(f1).then(function(data) {
                console.log("success 1: "+data)
                return f2();
            })
            .then(function(data) {console.log("success 2: "+data)})
            .catch(function(data) {console.log("error: "+data)});

这很好,但是,它似乎是一个黑客。 在Angular中有继承的东西吗? 或者由于某种原因它是不必要的?

链的第一次调用是同步的,所以乍一看似乎异常,然后将其中引发的异常传递给$q ,然后调用错误回调,这是针对异步承诺拒绝(或实际上是异常)

引用$ q文档

Q有比q更多的功能

因此缺乏fCall功能听起来像团队决定可以删除的东西之一。 看起来你必须像你一样自己滚动。 您可能希望使用https://gist.github.com/leon/8800809之类的技术来使用fCall方法来装饰$q ,因此您可以使用它:

$q.fCall(f1).then(function()...

我知道这是一个较老的问题,但我今天也遇到了同样的问题并找到了答案,但我认为我不需要添加fCall()来实现这一点。 经过一番挖掘后,我发现今天可以在Angular v1.5中完成(不知道这在什么时候变得有效):

$q.when().then(() => f1)...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM