2013-06-12 65 views
8

我有一個函數需要傳遞給它的三個前面的promise的結果。一個是線性依賴的,另外兩個可以同時運行。我想用q.all來解析這三個promise,然後使用.spread將結果傳遞到第四個。我的代碼不起作用。任何幫助,將不勝感激。kriskowal/q node.js q.all和spread

var p1 = doWork(data); 
var p2 = p1.then(doMoreWork); 
var p3 = doConcurrentWork(data); 

return q.all([p1,p2,p3]).spread(funcWith3params) 
     .fail(function(err) { 
      console.log(err): 
     } 

我可以跟蹤節點檢查器中的代碼,看到前3個承諾被調用。但是,.spread調用的函數沒有被調用。任何線索爲什麼?另外.fail也沒有被擊中。

+0

我假設你打算在那裏放置一個關閉''''。 – Sukima

回答

7

在內部傳播呼叫q.all。

這裏是從q.js用於擴展的代碼:

Q.spread = spread; 
function spread(promise, fulfilled, rejected) { 
    return when(promise, function (valuesOrPromises) { 
     return all(valuesOrPromises).then(function (values) { 
      return fulfilled.apply(void 0, values); 
     }, rejected); 
    }, rejected); 
} 

注意,它預計解析爲一個數組或數組作爲第一個參數的承諾。

因此您的通話應該是這樣的:

var p1 = doWork(data); 
var p2 = p1.then(doMoreWork); 
var p3 = doConcurrentWork(data); 

return q.spread([p1,p2,p3], funcWith3params, function(err) { 
     console.log(err): 
    }); 

然而,原來的通話應該正常工作。不知道爲什麼沒有。

3

來表達您所提供的示例中,最簡潔的方法是:

var p1 = doWork(data); 
var p2 = p1.then(doMoreWork); 
var p3 = doConcurrentWork(data); 

return Q.spread([p1, p2, p3], funcWith3params) 
    .done(); 

然而,原來是正確的,因爲寫的。

我懷疑問題是一個或多個輸入承諾永遠不會解決。嘗試使用超時來隔離問題。

var p1 = doWork(data).timeout(1000, 'p1 timed out'); 
var p2 = p1.then(doMoreWork).timeout(1000, 'p2 timed out'); 
var p3 = doConcurrentWork(data).timeout(1000, 'p3 timed out'); 

return Q.spread([p1, p2, p3], funcWith3params) 
    .done(); 
+2

我見過沒有參數的'.done()'和一些args的例子。有差異和/或最佳做法嗎? – Sukima

+2

@Sukima'done()'用於明確地關閉承諾鏈,即您不能再期待'then'處理程序觸發超出「done」的調用。 – Renaud