2015-07-12 67 views
6

爲了讓這個問題對儘可能多的人有用,我將排除我的具體實現細節,超出了我在以下使用藍鳥承諾庫和Node + Express的事實。Bluebird Promise Chains:'Catch'與結果

所以,讓我們說,我有以下的鏈(其中P返回一個承諾,res是快速HTTP響應對象):

P().then(function(){ 
    // do nothing if all went well (for now) 
    // we only care if there is an error 
}).catch(function(error){ 
    res.status(500).send("An error occurred"); 
}).then(function(){ 
    return P(); 
}).then(function(pVal1){ 
    return [pVal1, P()]; 
}) // TODO: catch an error from P() here and log pVal1 
.spread(function(pVal1, pVal2){ 
    if(pVal1 === pVal2) { 
     console.log("Success!"); 
    } else { 
     console.log("Failure"); 
    } 
}); 

當我把上面的TODO評論是在那裏我會喜歡發現我撥打P時可能發生的錯誤。如果我遇到了錯誤,我想登錄pVal1,然後發送500錯誤,就像在第一次捕獲中所做的那樣。但是,我不確定這是否可能與我如何構建我的連鎖店。

我相信我需要做一些「分支」,但我不認爲我理解這個概念足夠好,以阻止JavaScript的異步性質從我這裏得到最好的結果!因此,任何幫助都被完全讚賞。

+0

如果我這樣做是完全錯誤的,請讓我知道! – nmagerko

+1

@torazaburo不,它不是。 –

+0

@BenjaminGruenbaum爲什麼不呢? –

回答

2

不要忘記在鏈條末尾發現錯誤。這也是發送回覆的地方。

鏈中間的捕獲錯誤是間歇性錯誤處理;該鏈繼續運行,所以不要只發送響應。

這是值得嘗試一下:

// example middleware 
 
function handle(req, res, next) { 
 
    log("----------------"); 
 
    return async("p1", "foo").then(function (pVal1) { 
 
     return pVal1; 
 
    }).then(function (pVal1) { 
 
     var p2a = async("p2a", "bar"), 
 
      p2b = async("p2a", "bar").catch(function (error) { 
 
       log("Logging: " + error + " (pVal1 " + pVal1 + ")"); 
 
      }); 
 
     return [p2a, p2b]; 
 
    }).spread(function (pVal1, pVal2) { 
 
     if (pVal1 === pVal2) { 
 
      res.send("Success!"); 
 
     } else { 
 
      res.send("Failure"); 
 
     } 
 
    }).catch(function (error) { 
 
     res.status(500).send("An error occurred"); 
 
     log("Logging: " + error); 
 
    }); 
 
} 
 

 
// --------------------------------------------------------------------- 
 
// mockup response object 
 
var res = { 
 
    status: function (code) { 
 
     log("Sending status: " + code); 
 
     return this; 
 
    }, 
 
    send: function() { 
 
     log("Sending response: " + [].join.call(arguments, " ")); 
 
     return this; 
 
    } 
 
}; 
 

 
// mockup promise generator 
 
function async(name, value) { 
 
    return new P(function (resolve, reject) { 
 
     if (confirm("let " + name + " succeed?")) { 
 
      log(name + " succeeds..."); 
 
      resolve(value); 
 
     } else { 
 
      log(name + " fails..."); 
 
      reject(name + " has failed"); 
 
     } 
 
    }); 
 
} 
 

 
function log() { 
 
    var msg = document.createElement("DIV"); 
 
    msg.textContent = [].join.call(arguments, " "); 
 
    document.getElementById("log").appendChild(msg) 
 
    document.body.scrollTop = document.body.scrollHeight; 
 
}
button { 
 
    position: fixed; 
 
    top: 5px; 
 
}
<script src="http://cdnjs.cloudflare.com/ajax/libs/bluebird/2.9.33/bluebird.min.js"></script> 
 

 
<button onclick="handle(null, res, null)">Go</button> 
 

 
<div id="log"></div>

+0

啊,'then'裏面的'catch'可能是我錯過的東西。我甚至沒有想過如此構造它。這個例子也使這個很好的答案! – nmagerko

1

如果您使用顯式Promise.all不是返回數組.spread的這是可能的。

}).then(function(pVal1){ 
    // this becomes a `Promise.all` - the aggregation is explicit 
    var all = Promise.all([pVal1, P()]); 
    all.catch(function(e){ // "branching", we both return and `catch` the promise 
     console.log("Error, pVal1 is", pVal1); 
    }); 
    return all; // return it 
}).spread(function(pVal1, pVal2){ 
     // .... 
}); 
+0

這種類型的代碼不會導致「未處理的拒絕」嗎? – Bergi

+0

@Bergi試試:) –

+0

好的,我做了,是的,它記錄了一個未處理的拒絕(我的預感是正確的,但我仍然不完全瞭解「未處理」的條件)。但是,我們想要嗎? – Bergi

相關問題