Execute Promise.all en série

J'ai un tableau qui contient une série de promesses, et chaque tableau intérieur pourrait avoir des promesses de 4k, 2k ou 500.

Au total, il y a environ 60k promesses et je peux le tester avec d'autres valeurs aussi.

Maintenant, je dois exécuter Promise.all(BigArray[0]) .

Une fois que le premier ensemble interne est terminé, je dois exécuter la prochaine Promise.all(BigArray[1]) et ainsi de suite.

Si j'essaie d'exécuter une Promise.all(BigArray) il lance:

Erreur fatale call_and_retry_2 allocation échouée – traitement hors mémoire

Je dois l'exécuter chaque promesse en série, pas en parallèle, ce que je pense que c'est ce que Node fait. Je ne devrais pas utiliser de nouvelles libs, mais je suis prêt à considérer la réponse!

Modifier:

Voici un exemple de code:

 function getInfoForEveryInnerArgument(InnerArray) { const CPTPromises = _.map(InnerArray, (argument) => getDBInfo(argument)); return Promise.all(CPTPromises) .then((results) => { return doSomethingWithResults(results); }); } function mainFunction() { BigArray = [[argument1, argument2, argument3, argument4], [argument5, argument6, argument7, argument8], ....]; //the summ of all arguments is over 60k... const promiseArrayCombination = _.map(BigArray, (InnerArray, key) => getInfoForEveryInnerArgument(InnerArray)); Promise.all(promiseArrayCombination).then((fullResults) => { console.log(fullResults); return fullResults; }) } 

Promise.all() va vérifier chacun de vos résultats prometteurs qui sont passés en arguments en parallèle , et rejetteront la première erreur ou résolvent à la fin de toutes les promesses.

Du MDN :

Promise. Tout le monde passe un ensemble de valeurs de toutes les promesses dans l'objet itératif qui a été transmis. Le tableau de valeurs maintient l'ordre de l'objet original itératif, et non l'ordre dans lequel les promesses ont été résolues. Si quelque chose qui se passe dans le tableau itératif n'est pas une promesse, il est converti en un par Promise.resolve.

Si l'une des promesses promulguées rejette, toute la Promesse rejette immédiatement avec la valeur de la promesse qui a rejeté, en rejetant toutes les autres promesses qu'elles aient ou non résolu. Si un tableau vide est passé, cette méthode se résout immédiatement.

Si vous devez exécuter toutes vos promesses en série, la méthode Promise.all() ne fonctionnera pas pour votre application. Au lieu de cela, vous devez trouver une approche itérative pour résoudre vos promesses. Cela va être difficile; Node.js est de nature asynchrone, et l'utilisation de boucles (à ma connaissance et à mon expérience) ne sera pas bloquée jusqu'à ce qu'une réponse soit reçue d'une promesse dans une boucle.

Modifier:

Une bibliothèque existe appelée série de promesses-nœuds , ce qui, je pense, peut vous aider un peu ici. Comme vous avez déjà promis, vous pourriez simplement passer votre BigArray :

 promiseSeries(BigArray).then( (results) => { console.log(results); }); 

À mon avis personnel, votre approche de commencer avec les promesses 60k + prendra non seulement beaucoup de temps, mais aussi des ressources sur le système qui les exécutent (c'est pourquoi vous manque de mémoire). Je pense que vous voudrez peut-être considérer une meilleure architecture pour l'application.

Edit2, qu'est-ce qu'une promesse ? ::

Une promesse représente le résultat d'une opération asynchrone, qui peut prendre l'un des trois états:

  1. En attente: l'état de départ de la promesse
  2. Réalisé: état de promesse représenté par une opération réussie
  3. Rejeté: état de promesse représenté par une opération échouée

Les promesses sont immuables une fois qu'elles sont remplies ou des états rejetés. Vous pouvez chaîner les promesses (idéal pour éviter les rappels répétés), ainsi que les imbriquer (lorsque la fermeture est une préoccupation). Il existe de nombreux articles géniaux sur le Web pour cela, voici un que j'ai trouvé informatif .

Bonne réponse ici Rappel après tout asynchrone pour tous les rappels sont terminés

 function asyncFunction (item, cb) { setTimeout(() => { console.log('done with', item); cb(item*10); }, 1000*item); } let requests = [1,2,3].map((item) => { return new Promise((resolve) => { asyncFunction(item, resolve); }); }) Promise.all(requests).then( // () => console.log('done') function(arr){ console.log(arr) console.log('done') } ); 

La promesse de bluebird de la bibliothèque offre une méthode d'aide appelée Promise.map , qui prend un tableau ou une promesse d'un tableau comme son premier argument et mappe tous ses éléments à un tableau de résultats, ce qui à son tour est également promis. Peut-être que vous pourriez essayer quelque chose comme ceci:

 return Promise.map(BigArray, function(innerArray) { return Promise.all(innerArray); }) .then(function(finishedArray) { // code after all 60k promises have been resolved comes here console.log("done"); }); 

Mais comme déjà indiqué précédemment, il s'agit encore d'une tâche très intensive qui peut consommer toute la mémoire disponible.