2015-04-01 102 views
0

我想知道如果有藍鳥的方式承諾.catch拋出的錯誤,然後處理一些沒有分支(嵌套承諾)的具體行動。藍鳥承諾並抓分支

說我有

doSomethingAsync() 
.then(function (result) { 
    if (!result) 
    throw new CustomError('Blah Blah'); 

    if (result == 0) 
    throw new CustomError2('Blah Blah Blah'); 

    return result; 
}) 
.then(function (result) { 
    console.log('Success, great!'); 
}) 

.catch(CustomError, function (error) { 
    // Oh CustomError! 
    return saveSomethingAsync(); 
}) 
.then(function (saved) { 
    // Should only be executed if an CustomError has been thrown 
    console.log("Let's try again"); 
    return doSomethingAsync(); 
}) 

.catch(CustomError2, function (error) { 
    // Oh CustomError2! 
}) 
.delay(15000) // Don't try again now ! 
.then(function() { 
    // Should only be executed if an CustomError2 has been thrown 
    console.log("Let's try again after some long delay"); 
    return doSomethingAsync(); 
}) 

.catch(function (error) { 
    // Should catch all random errors of the chain 
}) 

當我執行這個代碼,我得到一些行爲:

  • 如果沒有錯誤拋出,我得到 「成功,太棒了!」並與「我們經過長期等待後重試」
  • 如果CustomError拋出,我得到「讓我們再試一次」
  • 如果CustomError2拋出,我得到「我們經過長期等待後重試」
再次啓動

我無法弄清楚這個流程發生了什麼。 應該很好寫這樣的東西,而不是將錯誤的特定代碼嵌套在新的承諾鏈中。

回答

1

.catch拋出的錯誤,然後處理一些具體的行動沒有分支

號因爲那分支。在這裏嵌套是完全自然的。你甚至可以使用同步隱喻來想到這一點,它會是一樣的。

我無法弄清楚這個流程發生了什麼。

  • 如果沒有錯誤發生,我會得到「成功,太棒了!」並與「我們經過長期等待後重試」

嗯再次啓動,這是奇怪的,因爲「讓我們再試一次」(無延遲)之前被鏈接。你最終應該得到兩個日誌。您鏈順序處理:

doSomethingAsync() // returns a result 
then return result // first callback: continues with it 
then console.log('Success, great!') // next callback: logs something 
catch // is ignored because no rejection 
then console.log("Let's try again"); // next callback: logs something 
     return doSomethingAsync();  //    and returns a result 
catch // that result, not being a rejection, is ignored here 
delay // fulfillment is delayed 
then console.log("Let's try again after some long delay"); // next callback again logs 
     return doSomethingAsync();       // and returns a result 
catch // is ignored again 
  • 如果引發CustomError,我得到 「讓我們再試一次」

是的,因爲saveSomethingAsync();,先前承諾的結果,被執行,所以鏈中的下一個.then()回調執行。

  • 如果CustomError2被拋出,我得到「讓我們再試一次經過一番長時間的延遲」

是的,因爲錯誤一路冒泡到.catch(CustomError2, …)它最終被處理。在途中,沒有回調被執行。在the error was handled之後,承諾完成,鏈中的下一個.then()稱爲其回調。

我覺得你真的想在這裏是什麼

doSomethingAsync() 
.then(function(result) { 
    if (!result) 
    // CustomError('Blah Blah'); 
    // Oh CustomError! 
    return saveSomethingAsync(); 
    .then(function(saved) { 
     console.log("Let's try again"); 
     return doSomethingAsync(); 
    }); 
    else if (result == 0) 
    // CustomError2('Blah Blah Blah'); 
    // Oh CustomError2! 
    return Promise.delay(15000) // Don't try again now ! 
    .then(function() { 
     console.log("Let's try again after some long delay"); 
     return doSomethingAsync(); 
    }) 
    else 
    console.log('Success, great!'); 
    // return undefined implied 
}).catch(function (error) { 
    // does catch all random errors of the chain 
    // thrown by any of the doSomethingAsync() or of the saveSomethingAsync 
}) 
+0

好吧,我明白,承諾鏈順序執行,我會去嵌套。 但是,我想繼續拋出Errors而不立即處理它們,如果在帶有嵌套promise的'.catch(CustomError,...)'中拋出一個錯誤,會發生什麼? – EthanSbbn 2015-04-02 11:42:16

+0

與每個回調相同:'.catch()'返回的承諾被拒絕,並且鏈中的下一個事物將相應地執行。也許[此圖](http://stackoverflow.com/a/24663315/1048572)也有幫助 – Bergi 2015-04-02 13:49:16