2013-06-12 17 views
8

Ho una funzione che richiede il risultato di tre precedenti promesse passate. Uno è linearmente dipendente e gli altri due possono essere eseguiti contemporaneamente. Voglio usare q.all per risolvere le tre promesse, e poi passare i risultati sul quarto usando .spread. Il mio codice tuttavia non funziona. Qualsiasi aiuto sarebbe apprezzato.kriskowal/q node.js q.all e 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): 
     } 

posso rintracciare il codice del nodo-ispettore e vedere che i primi 3 promesse sono chiamati. Tuttavia, la funzione che chiamate .spread non viene chiamata. Qualche indizio sul perché? Anche .fail non viene colpito neanche.

+0

Immagino che tu abbia inteso porre una chiusura ')' lì. – Sukima

risposta

7

Chiamate di dispersione q.tutto internamente.

Ecco il codice per la diffusione da 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); 
} 

Nota che si aspetta una promessa che si risolve in un array o un array come primo argomento.

Pertanto la chiamata dovrebbe essere simile a questo:

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): 
    }); 

Tuttavia, la chiamata originale dovrebbe funzionare così. Non sono sicuro del perché no.

3

Il modo più sintetico per esprimere l'esempio che ci hai fornito è:

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

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

Tuttavia, l'originale è corretto come scritto.

Sospetto che il problema sia che una o più delle promesse di input non si risolvono mai. Prova a utilizzare i timeout per isolare il problema.

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

Ho visto l'uso di '.done()' senza argomenti e qualche esempio con argomenti. C'è una differenza e/o una buona pratica? – Sukima

+2

@Sukima 'done()' è usato per chiudere esplicitamente la catena di promessa, cioè non ci si può aspettare che più 'then' gestori si attivino oltre la chiamata a 'done'. – Renaud