2014-09-04 8 views
5

Quindi ho un metodo in un server angularjs che chiama un metodo che restituisce una promessa per ogni metodo in una matrice. Sto usando underscore _each per scorrere l'array. Voglio aspettare fino a quando l'intero array viene elaborato prima che io chiamo la riga finale del codice nel metodo ..

Quindi ...

function ProcessCoolStuff(coolStuffs) 
{ 
var stuff = []; 
_.each(coolStuffs, function(coolStuff) 
{ 
    //Some method using $q to return 
    makeStuffCooler(coolStuff).then(function(coolerStuff) 
    { 
    stuff.push(coolerStuff); 
    }); 
}); 
//Maybe Call a Display Method, or call event ect.. 
ShowAllMyCoolStuff(stuff); 
} 

Questo, naturalmente, non funziona .. il ciclo si completa e chiama "ShowAllMyCoolStuff" prima che makeStuffCooler venga eseguito per ciascun elemento. Quindi ... qual è il modo corretto di interagire con il metodo asincrono in modo che il mio metodo ShowAllMyCoolStuff attenda fino a quando la raccolta non viene popolata? Questa potrebbe essere la mia mancanza di esperienza con $ q e promesse in generale, ma sono bloccato. Grazie in anticipo.

+0

pena notare che se il browser è in esecuzione angolare, probabilmente si può contare su di esso per avere Array.prototype.forEach e Array.prototype.map.But sì, $ q.all è dove sta a. – pfooti

risposta

8

Si desidera utilizzare $q.all, che prende una serie di promesse. Quindi usa map invece di each e passa il risultato a $q.all(), che ti dà una promessa che aspetta tutti loro. Non è nemmeno necessario che l'array stuff venga riempito manualmente, ma è sufficiente utilizzare il valore di risoluzione di tale nuova promessa.

function processCoolStuff(coolStuffs) { 
    return $q.all(_.map(coolStuffs, makeStuffCooler)); 
} 
processCoolStuff(…).then(showAllMyCoolStuff); 
+2

Bello, grazie. Questo è esattamente ciò di cui avevo bisogno .. Ho pensato che avesse qualcosa a che fare con $ q.all .. Anche +1 su come eliminare l'array riempito manualmente. –

0
$q.all([promise1,promise2,promise3,etc]) 
.then(function(results){ 
    alert("This alert will happen after all promises are resolved."); 
}) 
0

dopo aver letto la domanda e la risposta corrispondente, ho preso la strada giusta. Grazie mille! Ma per l'ultima soluzione di lavoro ho impiegato un'altra ora per far funzionare tutti i casi d'uso. Ecco perché vorrei condividere un esempio di codice che contiene promesse concatenate che includono una serie di promesse di attesa per la risoluzione.

Usa sfondo del caso è un'importazione di file sul lato server (nodoJs) dopo il caricamento. Ho usato delle promesse per restituire uno stato e un risultato HTTP appropriati.

readFile: function (fileName) { 
    if (fileName) { 
     var deferred = Q.defer(); 
     var self = this; 
     converter({input: fileName}, function (error, userData) { 
      if (error) { 
       deferred.reject(error); 
      } 
      self.storeUsers(error, userData) 
       .then(function (success) { 
        if (success) { 
         deferred.resolve(success) 
        } 
       }) 
       .fail(function (error) {      
        deferred.reject(error)      
       }); 
     }); 
     return deferred.promise; 
    } 
}, 

storeUsers: function (error, data) { 
    return Q.all(_.map(data, function (users, emailAddress) { 
     var deferred = Q.defer(); 
     userRepository.findUserByEmail(emailAddress, function (user) { 
      //... 
      user.save(function (error) { 
       if (error) { 
        deferred.reject(error); 
       } else { 
        deferred.resolve(emailAddress); 
       } 
      }); 

     }); 
     return deferred.promise; 
    })); 
} 

La speranza che aiuta anche!

Acclamazioni Ben