亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何正確地打破承諾鏈?

如何正確地打破承諾鏈?

茅侃侃 2019-07-02 14:24:51
如何正確地打破承諾鏈?基于以下問題:然后是jQuery鏈接和級聯,然后是而被接受的答案,我想打破承諾鏈在某一點,但還沒有找到正確的方式。確實有倍數 員額 關于但我還是迷路了。以原始問題中的示例代碼為例:Menus.getCantinas().then(function(cantinas){ // `then` is how we chain promises     Menus.cantinas = cantinas;     // if we need to aggregate more than one promise, we `$.when`     return $.when(Menus.getMeals(cantinas), Menus.getSides(cantinas));}).then(function(meals, sides){      // in jQuery `then` can take multiple arguments     Menus.sides = sides; // we can fill closure arguments here     Menus.meals = meals;     return Menus.getAdditives(meals, sides); // again we chain}).then(function(additives){     Menus.additives = additives;     return Menus; // we can also return non promises and chain on them if we want}).done(function(){      // done terminates a chain generally.      // edit HTML here});我怎么打破鎖鏈cantinas.length == 0?我不想得到食物,也不想得到添加物,坦率地說,我想稱之為某種“空洞的結果”回調。我試過以下幾種方法很丑(但有效.)教我正確的方法。這仍然是一個有效的結果,所以不是“失敗”本身,只是空洞的結果,我想說。var emptyResult = false;Menus.getCantinas().then(function(cantinas){     Menus.cantinas = cantinas;     if (cantinas.length == 0) {       emptyResult = true;       return "emptyResult"; //unuglify me     }     return $.when(Menus.getMeals(cantinas), Menus.getSides(cantinas));}).then(function(meals, sides){      if (meals == "emptyResult") return meals;  //look at my ugliness...     Menus.sides = sides;     Menus.meals = meals;     return Menus.getAdditives(meals, sides);}).then(function(additives){     if (additives == "emptyResult") return additives;     Menus.additives = additives;     return Menus;}).done(function(){    if (emptyResult)      //do empty result stuff    else      // normal stuff});
查看完整描述

3 回答

?
藍山帝景

TA貢獻1843條經驗 獲得超7個贊

首先,我認為最好是說你是在“繞開”承諾鏈,而不是“打破”它。

正如您所說,在一些地方對“emptyResult”進行測試是非常糟糕的。幸運的是,在遵循相同的不執行部分承諾鏈的一般原則的同時,還提供了一種更優雅的機制。

另一種機制是使用承諾拒絕來控制流程,然后在鏈的后面重新檢測特定的錯誤條件,并將其重新放到成功的路徑上。

Menus.getCantinas().then(function(cantinas) {
    Menus.cantinas = cantinas;
    if(cantinas.length == 0) {
        return $.Deferred().reject(errMessages.noCantinas);
    } else {
        return $.when(Menus.getMeals(cantinas), Menus.getSides(cantinas));
    }}).then(function(meals, sides) {
    Menus.sides = sides;
    Menus.meals = meals;
    return Menus.getAdditives(meals, sides);}).then(function(additives) {
    Menus.additives = additives;
    return Menus;}).then(null, function(err) {
    //This "catch" exists solely to detect the noCantinas condition 
    //and put the chain back on the success path.
    //Any genuine error will be propagated as such.
    //Note: you will probably want a bit of safety here as err may not be passed and may not be a string.
    return (err == errMessages.noCantinas) ? $.when(Menus) : err;}).done(function(Menus) {
    // with no cantinas, or with everything});var errMessages = {
    'noCantinas': 'no cantinas'};

從好的方面來說,我發現缺乏嵌套有助于更好地閱讀自然成功的道路。而且,至少對我來說,如果需要的話,這種模式需要最少的精神雜耍來適應更多的旁路。

另一方面,這種模式的效率略低于Bergi。cantinas.length == 0路徑需要多一個(如果多個旁路被編碼,則每個旁路需要一個)。此外,此模式還需要可靠地重新檢測特定錯誤條件,因此errMessages對象-有些人可能會找到貶低。


查看完整回答
反對 回復 2019-07-02
?
慕田峪7331174

TA貢獻1828條經驗 獲得超13個贊

聽起來像你支部不折斷-你想繼續和往常一樣done..承諾的一個優點是,它們不僅是連鎖的,而且可以是嵌套和非嵌套沒有限制。在你的例子中,你可以把你想要“掙脫”的鏈條的一部分放在你的if-聲明:

Menus.getCantinas().then(function(cantinas) {
    Menus.cantinas = cantinas;

    if (cantinas.length == 0)
        return Menus; // break!

    // else
    return $.when(Menus.getMeals(cantinas), Menus.getSides(cantinas))
    .then(function(meals, sides) {
        Menus.sides = sides;
        Menus.meals = meals;
        return Menus.getAdditives(meals, sides);
    }).then(function(additives) {
        Menus.additives = additives;
        return Menus;
    });}).done(function(Menus) {
    // with no cantinas, or with everything});


查看完整回答
反對 回復 2019-07-02
?
蕭十郎

TA貢獻1815條經驗 獲得超13個贊

對于使用內置瀏覽器承諾的人來說,他們需要尋找一種方法來停止承諾鏈,而不讓所有消費者都知道拒絕案例,從而觸發任何鏈接。thencatch或者扔東西Uncaught (in promise)錯誤,您可以使用以下方法:

var noopPromise = {
  then: () => noopPromise, 
  catch: () => noopPromise}function haltPromiseChain(promise) {
  promise.catch(noop)

  return noopPromise}// Use it thus:var p = Promise.reject("some error")p = haltPromiseChain(p)p.catch(e => console.log(e))
   // this never happens

從根本上說,nooppro而論是一個基本的存根承諾接口,它使用鏈接函數,但從不執行任何函數。這依賴于這樣一個事實,即瀏覽器顯然使用鴨子類型來確定某件事情是否是一種承諾,所以YMMV(我在Chrome 57.0.2987.98中測試了這一點),但如果這成為一個問題,您可能會創建一個實際的承諾實例,并對其當時和捕獲方法進行中性處理。


查看完整回答
反對 回復 2019-07-02
  • 3 回答
  • 0 關注
  • 540 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號