2014-07-07 43 views
2

我想知道是否有辦法創建一個承諾鏈,我可以基於一系列if語句構建並以某種方式在最後觸發它。例如:Q承諾 - 創建一個動態承諾鏈,然後觸發它

// Get response from some call 
callback = (response) { 
    var chain = Q(response.userData) 

    if (!response.connected) { 
     chain = chain.then(connectUser) 
    } 

    if (!response.exists) { 
     chain = chain.then(addUser) 
    } 

    // etc... 

    // Finally somehow trigger the chain 
    chain.trigger().then(successCallback, failCallback) 
} 

回答

1

承諾代表已經開始的操作。由於承諾鏈已經運行,因此您不能trigger()承諾鏈。

雖然您可以通過創建延遲然後排隊並最終解決此問題來解決此問題,但這不是最佳選擇。如果從最後一行降.trigger不過,我懷疑你的任務將如預期 - 唯一的區別是,它會排隊的操作和啓動它們,而不是等待:

var q = Q(); 
if(false){ 
    q = q.then(function(el){ return Q.delay(1000,"Hello"); 
} else { 
    q = q.then(function(el){ return Q.delay(1000,"Hi"); 
} 
q.then(function(res){ 
     console.log(res); // logs "Hi" 
}); 

這裏的關鍵點是:

  • 承諾代表已經開始的操作。
  • 即使在解決問題後,您仍然可以將.then處理程序附加到承諾,並且仍然可以執行預測。

祝你好運,快樂編碼

+0

是的,我試過了,我發現它是我的代碼中的另一個錯誤,它阻止了它的工作。修正了這一切,它全是綠色的:) – Maruf

1

正如本雅明說...

...但你可能也想考慮的東西略有不同。嘗試從內向外翻譯代碼;無條件地構建當時的鏈,並在.then()回調中執行測試。

function foo(response) { 
    return = Q().then(function() { 
     return (response.connected) ? null : connectUser(response.userData); 
    }).then(function() { 
     return (response.exists) ? null : addUser(response.userData);//assuming addUser() accepts response.userData 
    }); 
} 

我想你會返回空值脫身 - 如果null不工作,然後嘗試Q()(在兩個地方)。

如果我什麼傳遞給addUser()假設是正確的,那麼你就不需要擔心傳遞數據環比下滑 - response由外部函數構成的封閉仍然可用。如果這個假設不正確,那麼不用擔心 - 只需安排connectUser返回任何必要的內容並在第二個.then中選擇它。

我認爲這種方法比條件鏈構建更優雅,儘管效率較低。也就是說,你不可能注意到這種差異。