原文: When is .then(success, fail) considered an antipattern for promises?
問題
我在bluebrid promise FAQ上面看到, 在那里講到.then(sucess, fail)
是一個antipattern. 我不能理解他關於try
和catch
的解釋. 下面這個例子有什么錯誤.
some_promise.call()
.then(function(res) {logger.log(res), function(err) {logger.log(err)}})
這好像表示出, 下面才是正確的使用方式.
some_promise_call()
.then(function(res) {logger.log(res)})
.catch(function(err) {logger.log(err)})
這兩個例子有什么不同?
解答
他們有什么不同
這個.then()
會返回一個promise, 這個promise,以防在回調函數中出現的錯誤. 以便進行rejected的執行. 這意味着, 當你成功的logger
執行的過程中, 發生了錯誤, 這個錯誤就會通過下一個.catch
中的回調函數捕獲, 但是沒有辦法在sucess
后面的fail
回調函數所捕獲.
下面是一張控制流程圖:
在同步代碼中展示:
// some_promise_call().then(looger.log, looger.log)
then: {
try {
var resluts = some_call()
} catch(e) {
logger.log(e)
break then;
}
// else
looger.log(resluts)
}
第二個log
(就像是在.then
中的第一個參數), 只有在沒有異常發生的時候執行. 這種塊級運行和break
語法看起來有點奇怪. 這其實就是Python中的try-except-else
(推薦閱讀).
// some_promise_call().then(logger.log).catch(logger.log)
try {
var results = some_call()
logger.log(results)
} catch (e) {
logger.log(e)
}
這個catch
也會捕獲來着成功logger這個函數執行中所發生的異常.
他們有非常大的不同.
我不理解他關於try和catch的解釋
分歧點就是在於你想要每一步都捕獲錯誤, 還是不喜歡在鏈式中捕獲錯誤. 一種預期就是你希望所有的錯誤都通過同一種錯誤處理, 當然, 當你使用antipattern
(反模式)的時候, 錯誤在一些then的回調中並沒有進行處理.
然而, 這種模式的確非常有用. 當你確實希望錯誤發生的時候, 只在那一步進行處理, 並且你希望做一些完全不同的錯誤處理. 也就是這個錯誤是不可恢復的. 注意, 那就是你的流程控制分支, 當然, 在某些情況下他會非常實用.
關於你這個例子的錯誤
// 詢問錯誤的例子:
some_promise_call()
.then(function(res) {logger.log(res)}), function(err) {logger.log(err}})
當你需要重復你的回調函數的時候, 也就是catch后面繼續執行的時候, 最好這么處理:
some_promise_call()
.catch(function(e) {
return e // 這是完全可以的, 我們將會打印這個錯誤
})
.done(function(res) {
logger.log(res)
})
你也可以繼續使用.finally()
來處理.