2015-09-23 37 views
1

我有以下代碼(http://jsfiddle.net/tj1eo86s/):有沒有什麼辦法在處理錯誤時鏈接承諾,就好像承諾被嵌套一樣?

promise(1).then(function() { 
    console.log("OK1"); 
    promise(2).then(function() { 
     console.log("OK2"); 
     promise(3).then(function() { 
      console.log("OK3"); 
     }, function() { 
      console.log("KO3"); 
     }); 
    }, function() { 
     console.log("KO2"); 
    }); 
}, function() { 
    console.log("KO1"); 
}); 

如果承諾(2)被拒絕,輸出將是:

OK1 
KO2 

我怎樣才能獲得相同的行爲,而鏈接的承諾?

我試着用(http://jsfiddle.net/7goh0ds9/):

promise(1) 
.then(function() { 
    console.log("OK1"); 
    return promise(2); 
}, function() { 
    console.log("KO1"); 
}) 
.then(function() { 
    console.log("OK2"); 
    return promise(3); 
}, function() { 
    console.log("KO2"); 
}) 
.then(function() { 
    console.log("OK3"); 
}, function() { 
    console.log("KO3"); 
}); 

但輸出是:

OK1 
KO2 
OK3 

然後我試圖把在錯誤回調錯誤(http://jsfiddle.net/cyx6mohy/):

promise(1) 
.then(function() { 
    console.log("OK1"); 
    return promise(2); 
}, function() { 
    console.log("KO1"); 
    throw "KO1"; 
}) 
.then(function() { 
    console.log("OK2"); 
    return promise(3); 
}, function() { 
    console.log("KO2"); 
    throw "KO2"; 
}) 
.then(function() { 
    console.log("OK3"); 
}, function() { 
    console.log("KO3"); 
    throw "KO3"; 
}); 

但現在我有:

OK1 
KO2 
KO3 

我實際上理解了所有這些行爲,但我一直無法找到解決方案來處理錯誤,就好像承諾被嵌套一樣。

+0

我不太明白你的問題究竟是什麼。嵌套與鏈接是不同的結構,因此很難弄清楚如何讓一個結構在概念上與另一個結構行爲相同。當你得到一個被拒絕的承諾時,你完全控制下一步發生的事情。如果你處理拒絕,那麼你從拒絕處理程序返回的任何內容都將成爲延續值。如果拋出或返回拒絕處理程序拒絕的承諾,則父承諾將被拒絕,鏈中的下一個拒絕處理程序將被調用。接下來的評論中繼續... – jfriend00

+0

如果您處理拒絕並且不拋出或返回被拒絕的承諾,那麼鏈中的下一個成功處理器將被調用。通過「處理」拒絕並且不返回繼續錯誤,您已經「處理」了錯誤並繼續正常的成功處理。 – jfriend00

+0

@ jfriend00是的,謝謝你的解釋,這也是我讀過的(這就是爲什麼我說我實際上理解了所有這些行爲)。關鍵在於,我發現鏈式承諾比嵌套承諾更具可讀性和可維護性(特別是當您有許多承諾時),但嵌套承諾實際上按我需要的方式行事。所以問題是:當鏈接承諾時,如何處理錯誤,就像它們在承諾嵌套時處理一樣。 – sp00m

回答

2

如果你的問題是,如何我一般做鏈接處理錯誤的方式完全相同任意嵌套,答案是你不能以通用的方式。鏈接是一個根本不同的控制結構比任意嵌套。

您可以設計一個與鏈接基本相同的嵌套。或者,如果您希望在鏈式世界中模擬嵌套結構的特定錯誤處理行爲,則「可能」能夠在鏈式序列中使用適當的錯誤處理和控制流程來實現此目的。請注意,我說「可能」,因爲它完全取決於嵌套序列的作用。你也可能無法用純粹的鏈接來模擬它。

如果你的問題是我如何讓這個鏈式承諾序列產生這個特定的響應,當這個特定的承諾鏈拒絕時,那可能是可能的,但它會被編碼爲你的具體情況和期望的結果,而不是以某種通用的方式。

基本上,有理由使用鏈接,並有理由使用嵌套和原因使用兩者的組合。和你一樣,我更喜歡鏈接,因爲控制流和可讀性​​看起來更簡單,所以我總是從頭腦開始考慮這個結構,但是在我的代碼中肯定有一些時候我必須在某些操作中使用嵌套(通常是因爲分支決定或某些類型的所需錯誤處理)。

1

您可以用食指拒絕作爲參數,然後添加一個.catch和處理錯誤有:

var breakOnPromise = 2; 

function promise(i) { 
    return new Promise(function(resolve, reject) { 
     if (i == breakOnPromise) { 
      reject(i); // pass index to catch 
     } else { 
      resolve(); 
     } 
    }); 
} 

promise(1).then(function() { 
    console.log("OK1"); 
    return promise(2); 
}).then(function() { 
    console.log("OK2"); 
    return promise(3); 
}).then(function() { 
    console.log("OK3"); 
}).catch(function(i) { 
    // This is just for your case, 
    // but you could use an `if` statement 
    var err = ["KO1", "KO2", "KO3"][i - 1]; 
    console.log(err); 
});