Promise.all в JavaScript: как получить значение разрешения для всех promises?
Я написал следующий файл node.js:
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);
});
})
}
Как видите, я использую Promise.all
, чтобы дождаться обеих операций чтения файлов csv. Я не понимаю почему, но когда я запускаю код, строка 'console.log(result)'
не фиксируется.
Мой второй вопрос: я хочу, чтобы функция обратного вызова в Promise.all.then()
две разные переменные, в то время как каждая из них является результатом соответствующего обещания.
Ответы
Ответ 1
Первый вопрос
Promise.all
принимает множество обещаний
Изменить:
Promise.all(read_csv_file("devices.csv"), read_csv_file("bugs.csv"))
(добавить []
вокруг аргументов)
Promise.all([read_csv_file("devices.csv"), read_csv_file("bugs.csv")])
// ---------^-------------------------------------------------------^
Второй вопрос
Promise.all
разрешается с массивом результатов для каждого из обещаний, которые вы передали ему.
Это означает, что вы можете извлечь результаты в переменные, такие как:
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
});
Вы можете использовать ES6+ деструктурирующие для дальнейшего упрощения кода:
Promise.all([read_csv_file("devices.csv"), read_csv_file("bugs.csv")])
.then(function([first, second]) {
});
Ответ 2
Ответьте на второй вопрос:
Если вы хотите, чтобы обратный вызов then
принимал два разных аргумента, вы можете использовать Bluebird и его метод spread
, См:
Вместо .then(function (array) { ... })
и для доступа к array[0]
и array[1]
внутри вашего обработчика then
вы сможете использовать spread(function (value1, value2) { ... })
и иметь обе переменные, названные так, как вы хотите.
Это особенность Bluebird, это невозможно с простым Promise
.
Вы используете Bluebird так же, как Promise, например:
var P = require('bluebird');
// and in your code:
return new P(function (resolve, reject) { ...
// instead of:
return new Promise(function (resolve, reject) { ...
Конечно, вам не нужно называть его P
, но все, что вы хотите.
Дополнительные примеры см. в Bluebird Cheatsheets.