簡體   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