Promise.all in JavaScript: How to get resolve value for all promises?
Solution 1
First question
Promise.all
takes an array of promises
Change:
Promise.all(read_csv_file("devices.csv"), read_csv_file("bugs.csv"))
to (add []
around arguments)
Promise.all([read_csv_file("devices.csv"), read_csv_file("bugs.csv")])
// ---------^-------------------------------------------------------^
Second question
The Promise.all
resolves with an array of results for each of the promises you passed into it.
This means you can extract the results into variables like:
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
});
You can use ES6+ destructuring to further simplify the code:
Promise.all([read_csv_file("devices.csv"), read_csv_file("bugs.csv")])
.then(function([first, second]) {
});
Solution 2
Answer to your second question:
If you want the then
callback to accept two different arguemnts, then you can use Bluebird and its spread
method. See:
Instead of .then(function (array) { ... })
and having to access array[0]
and array[1]
inside of your then
handler you will be able to use spread(function (value1, value2) { ... })
and have both variables named as you want.
This is a feature of Bluebird, it's not possible with plain Promise
.
You use Bluebird just like Promise, e.g.:
var P = require('bluebird');
// and in your code:
return new P(function (resolve, reject) { ...
// instead of:
return new Promise(function (resolve, reject) { ...
Of course you don't have to name it P
but whatever you want.
For more examples see the Bluebird Cheatsheets.
CrazySynthax
Updated on April 30, 2020Comments
-
CrazySynthax almost 4 years
I wrote the following node.js file:
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); }); }) }
As you can see, I use
Promise.all
in order to wait for both operations of reading the csv files. I don't understand why but when I run the code the line'console.log(result)'
is not committed.My second question is I want that the callback function of
Promise.all.then()
accepts two different variables, while each one of them is the result of the relevant promise. -
CrazySynthax over 7 yearsthanks. And what about my second question? Now, result includes all the data from both files. How can get each file's data to a separate array?
-
CrazySynthax over 7 yearsthanks. Isn't there any way to do it without bluebird ?
-
rsp over 7 years@CrazySynthax No. A standard Promise has only
then
which gets an array for Promise.all. -
CrazySynthax over 7 yearsand if I use 'spread', how is error handling being committed? I didn't see a catch clause in the link.
-
rsp over 7 years@CrazySynthax You use
.spread(...).catch(...)
just like you would.then(...).catch(...)
. -
rsp over 7 years@CrazySynthax See the Bluebird cheatsheet