Reputation: 76
I have a doubt in using Promise.all. I need to have three functions with callbacks. So I am writing these three function inside Promise.all and then get all three functions result in .then() of Promise.all. Is it a proper way or is there any other way?
Upvotes: 0
Views: 1287
Reputation: 1507
You need to wrap the callbacks in a promise to resolve them all with Promise.all
So:
Promise.all([
new Promise(resolve => client.query(q1, function(err, result) { resolve(result); }) ),
new Promise(resolve => client.query(q2, function(err, result) { resolve(result); }) ),
new Promise(resolve => client.query(q3, function(err, result) { resolve(result); }) )
]).then(([q1, q2, q3]) => {
//do something with results
}).
If you need to handle errors you'll need to reject on error.
Hope that helps.
Upvotes: -1
Reputation: 1074335
It sounds like you're doing it right, yes; it would have been better if you'd shown code.
But let's say you want to start three processes, which are started by doThis()
, doThat()
, and doTheOther()
. You handle it like this:
Promise.all([
doThis(),
doThat(),
doTheOther()
])
.then(([thisResult, thatResult, theOtherResult]) => { // The destructuring is optional, of course
// ...use them...
})
.catch(error => {
// ...handle/report error...
});
Key bits:
Promise.all
(I used an array above)Promise.all
's promise rejects if any of the operations rejects.In a comment you've posted this code:
Promise.all([
client.query(q1,function(err,res){ dosomething();}),
client.query(q2,function(err,res){ dosomething();})
])
.then(() => {
dosomething()};
}) // <== Added missing }
.catch(e => {
console.log(e); // <== Added missing ;
}); // <== Added missing ;
That looks incorrect. Normally, when a function accepts a callback like you show query
doing, it doesn't return a promise. Check your documentation for the query
call you're making.
If it returns a promise, then you'd use it like this:
Promise.all([
client.query(q1).then(dosomething),
client.query(q2).then(dosomething)
])
.then(() => {
dosomething()};
}) // <== Added missing }
.catch(e => {
console.log(e); // <== Added missing ;
}); // <== Added missing ;
...assuming you want doSomething
to be called only when the query succeeds (your code was calling it whether the query succeeded or failed).
If query
doesn't return a promise, you'd wrap it in something that does, like this:
function doQuery(client, q) {
return new Promise((resolve, reject) => {
client.query(q, function(err, res) {
if (err) {
reject(err);
} else {
resolve(res);
}
});
});
}
then using that:
Promise.all([
doQuery(client, q1).then(doSomething),
doQuery(client, q2).then(doSomething)
])
.then(() => {
dosomething()};
}) // <== Added missing }
.catch(e => {
console.log(e); // <== Added missing ;
}); // <== Added missing ;
(Again, I've assumed doSomething
should only be called when the query was successful.)
These days, lots of APIs are adding promise features. Also, there's util.promisify
to wrap callback-style API functions in promises. Here's how you'd use that with your code
const doQuery = util.promisify(client.query.bind(client)); // Note the .bind(client)
Promise.all([
doQuery(q1).then(doSomething),
doQuery(q2).then(doSomething)
])
.then(() => {
dosomething()};
}) // <== Added missing }
.catch(e => {
console.log(e); // <== Added missing ;
}); // <== Added missing ;
Upvotes: 3