Come sapere quando tutte le Promesse sono risolte in un parametro “iterable” dinamico?

Il mio problema è che non so come sapere quando un array di promesse dinamiche ha tutte le promesse risolte.

Ecco un esempio:

var promiseArray = []; promiseArray.push(new Promise(){/*blablabla*/}); promiseArray.push(new Promise(){/*blablabla*/}); Promise.all(promiseArray).then(function(){ // This will be executen when those 2 promises are solved. }); promiseArray.push(new Promise(){/*blablabla*/}); 

Ho un problema qui. Il comportamento di Promise.all verrà eseguito quando le precedenti 2 promesse saranno risolte, MA, prima che queste 2 promesse siano state risolte, una terza promise dove aggiunta e questa nuova non sarà presa in considerazione.

Quindi, quello di cui ho bisogno, è qualcosa del tipo: “Hey Promise.all , hai un array dinamico da controllare”. Come posso farlo?

Ricorda che questo è solo un esempio. So che posso spostare la linea Promise.all fino all’ultima riga, ma in realtà le nuove promesse vengono aggiunte dynamicmente quando vengono risolte altre promesse, e le nuove promesse potrebbero aggiungere nuove promesse, quindi, è una matrice davvero dynamic.

Il vero caso d’uso che ho è qualcosa del genere:

  1. Io uso l’API di Twitter per verificare se ci sono nuovi Tweet (usando l’API di ricerca).
  2. Nel caso in cui ho trovato nuovi tweet, lo aggiungo a un MongoDB (qui abbiamo Promises).
  3. Nel caso in cui quei nuovi Tweets siano legati a un utente che non ho nel mio MongoDB (qui abbiamo nuove promesse perché devo andare su MongoDB per verificare se ho quell’utente), andiamo all’API di Twitter per ottenere le informazioni dell’utente (più promettenti) e aggiungiamo questi nuovi utenti a MongoDB (sì, più promesse).
  4. Poi, vado su MongoDB per inserire nuovi valori per associare i nuovi tweet a quei nuovi utenti (più promesse! Wiii!).
  5. Quando tutte le query su MongoDB vengono risolte (tutte le selezioni, gli aggiornamenti, gli inserimenti), chiude la connessione MongoDB.

Un altro esempio difficile:

 var allPromises = []; allPromises.push(new Promise(function(done, fail){ mongoDB.connect(function(error){ //Because mongoDB works with callbacks instead of promises if(error) fail(); else ajax.get('/whatever').then(function(){ if (somethingHappens) { allPromises.push(new Promise(function(done, fail){ //This promise never will be take in account // bla bla bla if (somethingHappens) { allPromises.push(new Promise(function(done, fail){ //This promise never will be take in account // bla bla bla })); } else { ajax.get('/whatever/2').then(function(){ if (somethingHappens) { allPromises.push(new Promise(function(done, fail){ //This promise never will be take in account // bla bla bla })); } }); } })); } else { ajax.get('/whatever/2').then(function(){ if (somethingHappens) { allPromises.push(new Promise(function(done, fail){ //This promise never will be take in account // bla bla bla if (somethingHappens) { allPromises.push(new Promise(function(done, fail){ //This promise never will be take in account // bla bla bla })); } else { ajax.get('/whatever/2').then(function(){ if (somethingHappens) { allPromises.push(new Promise(function(done, fail){ //This promise never will be take in account // bla bla bla })); } }); } })); } }); } }); }); })); Promise.all(allPromises).then(function(){ // Soooo, all work is done! mongodb.close()! }); 

Quindi, ora, un esempio di bellezza. Abbiamo bisogno di chiamare la funzione showAllTheInformation quando viene chiamata l’ultima (non sappiamo quale è l’ultima) promise. Come si fa?:

 var name = 'anonimus'; var date = 'we do not know'; function userClikOnLogIn() { $http.get('/login/user/password').then(function(data){ if (data.logguedOk) { $http.get('/checkIfIsAdmin').then(function(data){ if (data.yesHeIsAnAdmin) { $http.get('/getTheNameOfTheUser').then(function(data){ if(data.userHasName) { $http.get('/getCurrentDate').then(function(data){ currentDate = data.theNewCurrentDate; }); } }); } }); } }); } function showAllTheInformation() { alert('Hi ' + name + ' today is:' + date); } 

qui un altro esempio con più contesto: https://jsfiddle.net/f0a1s79o/2/