2014-09-09 10 views
10

Sto effettuando più query mongoDB in loop. e voglio inviare tutti i risultati come un unico array di dati. Ma quando uso il ritorno per inviare i dati, semplicemente restituisco undefined e non attendo i risultati di tutte le richieste DB. Ho anche provato a usare q.moulde ma lo stesso problema.Problema nel restituire i dati recuperati dalle query DB richiamate nel ciclo

Codice:

var getPrayerInCat = function(data){ 
    var result ; 
    var finalData = []; 
    if(data.length >0){ 
      data.forEach(function(data2){ 
       var id= data2.id; 
       Prayer.find({prayerCat:id},function(err,prayer){ 
        var deferred = Q.defer() 
        if (err) { // ... 
         console.log('An error has occurred'); 
         // res.send(err); 
         result= finalData = err 
        } else { 
         if(!prayer){ 
          // console.log(data2.id+'--0'); 
          data2.prayersCount = 0; 
          result = deferred.resolve(finalData.push(data2)) 
         } else { 
          // console.log(data2.id+'--'+prayer.length); 
          data2.prayersCount = prayer.length; 
          // console.log(prayer) 
          result = deferred.resolve(finalData.push(data2)) 
         } // else for data forward 
        } 
        deferred.promise; 
       }) 
       // deferred.resolve(finalData); 

      }) 
      /*if(finalData.length > 0) { return finalData;}*/ 
     } 
} 

FinalData viene restituito indefinito.

+0

Qual è 'q.moulde'? – Bergi

+0

è una promessa. Posso rimuoverlo, stavo cercando di risolvere il problema, quindi ho provato questa cosa –

+0

La funzione 'getPrayerInCat()' non restituisce nulla o restituisce nulla a un callback. Inoltre, sarebbe utile se si rimuovessero i commenti dal codice e si aggiornasse il post per includere ciò che dovrebbe essere l'output escluso. E dovresti tornare "deferred.promise;", invece di mostrarlo? –

risposta

14

Cominciamo con la regola generale per l'utilizzo di promesse:

Ogni funzione che fa qualcosa asincrona deve restituire una promessa

Quali funzioni sono questi nel vostro caso? È getPrayerInCat, il callback forEach e Prayer.find.

Hm, Prayer.find non restituisce una promessa ed è una funzione di libreria in modo che non possiamo modificarla. Regola 2 entra in gioco:

Create an immediate wrapper per ogni funzione che non

Nel nostro caso che è facile con Q's node-interfacing helpers:

var find = Q.nbind(Prayer.find, Prayer); 

ora abbiamo promette soltanto intorno, e non è più necessario alcun rinvio. Terza regola entra in gioco:

Tutto ciò che fa qualcosa con un risultato asincrono va in una .then callback

... e restituisce il risultato. Diavolo, quel risultato può anche essere una promessa se "qualcosa" fosse asincrono! Con questo, siamo in grado di scrivere la funzione di callback completa:

function getPrayerCount(data2) { 
    var id = data2.id; 
    return find({prayerCat:id}) 
// ^^^^^^ Rule 1 
    .then(function(prayer) { 
// ^^^^^ Rule 3 
     if (!prayer) 
      data2.prayersCount = 0; 
     else 
      data2.prayersCount = prayer.length; 
     return data2; 
//  ^^^^^^ Rule 3b 
    }); 
} 

Ora, abbiamo qualcosa di un po 'più complicato: un ciclo. Chiamando ripetutamente lo getPrayerCount() otterremo più promesse, le cui attività asincrone vengono eseguite in parallelo e risolte in ordine sconosciuto. Vogliamo aspettare tutti loro - cioè ottenere una promessa che si risolve con tutti i risultati quando ciascuna delle attività è terminata.

Per tali compiti complessi, non cercare di venire con la propria soluzione:

Controllare l'API della libreria

E ci troviamo Q.all, che fa esattamente Questo.Scrivendo getPrayerInCat è un gioco da ragazzi ora:

function getPrayerInCat(data) { 
    var promises = data.map(getPrayerCount); // don't use forEach, we get something back 
    return Q.all(promises); 
// ^^^^^^ Rule 1 
} 

Se abbiamo bisogno di fare qualcosa con la matrice che Q.all risolve, basta applicare l'articolo 3.

+0

Ho usato il tuo codice ma lo stesso problema è il modulo di ricerca e non vedo l'ora di tornare da db. Quindi il risultato finale non è definito. –

+0

getPrayerCat (''). Allora (function (dati) { getPrayerInCat (dati) }). Allora (function (data2) { console.log (data2) }) var getPrayerInCat = function (dati) { var risultato; var finalData = []; if (data.length> 0) { var promises = data.map (getPrayerCount); return Q.all (promesse); } } –

+0

function getPrayerCount (data2) { var id = data2.id; ritorno find ({prayerCat: id}) .then (function (preghiera) {! se (preghiera) data2.prayersCount = 0; altro data2.prayersCount = prayer.length; ritorno dati2; }) ; } –

Problemi correlati