web-dev-qa-db-fra.com

Promise.all en JavaScript: Comment obtenir une valeur de résolution pour toutes les promesses?

J'ai écrit le fichier node.js suivant: 

var csv = require('csv-parser');
var fs = require('fs')
var Promise = require('bluebird');
var filename = "devices.csv";
var devices;

Promise.all(read_csv_file("devices.csv"), read_csv_file("bugs.csv")).then(function(result) {
    console.log(result);
});


function read_csv_file(filename) {
    return new Promise(function (resolve, reject) {
            var result = []
            fs.createReadStream(filename)
                .pipe(csv())
                .on('data', function (data) {
                    result.Push(data)
                }).on('end', function () {
                resolve(result);
            });
    })
}

Comme vous pouvez le constater, j’utilise Promise.all afin d’attendre les deux opérations de lecture des fichiers csv. Je ne comprends pas pourquoi, mais lorsque je lance le code, la ligne 'console.log(result)' n'est pas validée. 

Ma deuxième question est que je veux que la fonction de rappel de Promise.all.then() accepte deux variables différentes, alors que chacune d’elles est le résultat de la promesse correspondante. 

6
CrazySynthax

Première question

Promise.all prend un tableau de promesses

Changement:

Promise.all(read_csv_file("devices.csv"), read_csv_file("bugs.csv"))

to (ajouter [] autour des arguments)

Promise.all([read_csv_file("devices.csv"), read_csv_file("bugs.csv")])
// ---------^-------------------------------------------------------^

Deuxième question

Le Promise.all résout avec un tableau de résultats pour chacune des promesses que vous avez passées.

Cela signifie que vous pouvez extraire les résultats dans des variables telles que:

Promise.all([read_csv_file("devices.csv"), read_csv_file("bugs.csv")])
  .then(function(results) {
    var first = results[0];  // contents of the first csv file
    var second = results[1]; // contents of the second csv file
  });

Vous pouvez utiliser ES6 + destructuring pour simplifier davantage le code:

Promise.all([read_csv_file("devices.csv"), read_csv_file("bugs.csv")])
  .then(function([first, second]) {

  });
19
nem035

Répondez à votre deuxième question:

Si vous souhaitez que le rappel then accepte deux arguments différents, vous pouvez utiliser Bluebird et sa méthode spread. Voir:

Au lieu de .then(function (array) { ... }) et devant accéder à array[0] et array[1] à l'intérieur de votre gestionnaire then, vous pourrez utiliser spread(function (value1, value2) { ... }) et faire nommer les deux variables à votre guise.

Ceci est une fonctionnalité de Bluebird, ce n’est pas possible avec un Promise simple.

Vous utilisez Bluebird comme Promise, par exemple:

var P = require('bluebird');
// and in your code:
return new P(function (resolve, reject) { ...
// instead of:
return new Promise(function (resolve, reject) { ...

Bien sûr, vous n’avez pas à le nommer P mais comme vous le souhaitez.

Pour plus d'exemples, voir Bluebird Cheatsheets .

1
rsp