web-dev-qa-db-fra.com

Promise.all (). Then () résoudre?

Utilisation de Node 4.x. Quand vous avez une Promise.all(promises).then() quelle est la bonne façon de résoudre les données et de les transmettre à la prochaine .then()?

Je veux faire quelque chose comme ça:

Promise.all(promises).then(function(data){
  // Do something with the data here
}).then(function(data){
  // Do more stuff here
});

Mais je ne suis pas sûr de savoir comment obtenir les données au 2e .then(). Je ne peux pas utiliser resolve(...) dans le premier .then(). J'ai compris que je pouvais le faire:

return Promise.all(promises).then(function(data){
  // Do something with the data here
  return data;
}).then(function(data){
  // Do more stuff here
});

Mais cela ne semble pas être la bonne façon de procéder ... Quelle est la bonne approche à cet égard?

76
Jake Wilson

Mais cela ne semble pas être la bonne façon de le faire ..

C’est bien la bonne façon de le faire (ou au moins une bonne façon de le faire). C’est un aspect essentiel des promesses, il s’agit d’un pipeline, et les données peuvent être traitées par les différents gestionnaires du pipeline.

Exemple:

const promises = [
  new Promise(resolve => setTimeout(resolve, 0, 1)),
  new Promise(resolve => setTimeout(resolve, 0, 2))
];
Promise.all(promises)
  .then(data => {
    console.log("First handler", data);
    return data.map(entry => entry * 10);
  })
  .then(data => {
    console.log("Second handler", data);
  });

(catch gestionnaire omis par souci de brièveté. Dans le code de production, toujours soit propager la promesse, soit gérer le rejet.)

Le résultat obtenu est:

 Premier manipulateur [1,2] 
 Second manipulateur [10,20] 

... parce que le premier gestionnaire obtient la résolution des deux promesses (1 et 2) sous forme de tableau, puis crée un nouveau tableau avec chacune de celles-ci multiplié par 10 et le renvoie. Le deuxième gestionnaire obtient ce que le premier gestionnaire a renvoyé.

Si le travail supplémentaire que vous effectuez est synchrone, vous pouvez également le mettre dans le premier gestionnaire:

Exemple:

const promises = [
  new Promise(resolve => setTimeout(resolve, 0, 1)),
  new Promise(resolve => setTimeout(resolve, 0, 2))
];
Promise.all(promises)
  .then(data => {
    console.log("Initial data", data);
    data = data.map(entry => entry * 10);
    console.log("Updated data", data);
    return data;
  });

... mais si c'est asynchrone, vous ne voudrez pas le faire car il finira par être imbriqué, et l'imbrication peut rapidement devenir incontrôlable.

126
T.J. Crowder