Is Node.Js Native Promise.All Processing in Parallel or Sequentially

Is Node.js native Promise.all processing in parallel or sequentially?

Is Promise.all(iterable) executing all promises?

No, promises cannot "be executed". They start their task when they are being created - they represent the results only - and you are executing everything in parallel even before passing them to Promise.all.

Promise.all does only await multiple promises. It doesn't care in what order they resolve, or whether the computations are running in parallel.

is there a convenient way to run an iterable sequencially?

If you already have your promises, you can't do much but Promise.all([p1, p2, p3, …]) (which does not have a notion of sequence). But if you do have an iterable of asynchronous functions, you can indeed run them sequentially. Basically you need to get from

[fn1, fn2, fn3, …]

to

fn1().then(fn2).then(fn3).then(…)

and the solution to do that is using Array::reduce:

iterable.reduce((p, fn) => p.then(fn), Promise.resolve())

Does Promise.all() run in sequential or parallel?

Javascript is a single threaded application. However, asynchronous calls allow you to not be blocked by that call. This is particularly useful when making REST API calls. For example your promise1() can make a REST API call and before it waits for the results, another REST API call can be made from promise2(). This pseudo-parallelism is thus achieved by not waiting on API servers to do the tasks and fire multiple such calls to either same or different API endpoints in parallel. This allows your code to continue executing that parts that are not dependent on resolution of the promises.

So yes, promise1(), promise2() and promise3() can be said to be running in parallel in that respect. And there is a chance that promise2() gets resolved before promise1() and so on. The function Promise.all() waits for all the promises provided to it to fulfill or at least one of them to fail.

Learn more about Javascript event loops in this video by Jake Archibald.

Promise.all() and parallel promises are they differ in node

The second approach will be more performant.

In the first example assume that each request takes 1 second to return, so you will take at least 3+ seconds to return your results as you wait for the result of one request before making the next.

In the second approach you make all the requests at once, and then wait for the IO callback. Once all the requests are handled the Promise.all() will resolve. If each request takes ~1 sec but is made in parallel your response will be about 1 second as well.

I would use syntax like the following however to maintain readability as you seem to be using async/await and don't need to have a reference to the promises.

try {
const [addresses, emails, phones] = await Promise.all([
searchArray.includes('address')
? axios('./getAddress') : Promise.resolve({}),
searchArray.includes('email')
? axios('./email') : Promise.resolve({}),
searchArray.includes('phone')
? axios('./phone') : Promise.resolve({}),
]);
return res.status(200).json({
addresses: addresses.data,
emails: emails.data,
phoneNumbers: phones.data,
});
} catch (err) {
return res.status(constants.HTTP_SERVER_ERROR).json(err);
}

Sequential execution of Promise.all

the Promises unfortunatelly does not allow any control of their flow. It means -> once you create new Promise, it will be doing its asynchronous parts as they like.

The Promise.all does not change it, its only purpose is that it checks all promises that you put into it and it is resolved once all of them are finished (or one of them fail).

To be able to create and control asynchronous flow, the easiest way is to wrap the creation of Promise into function and create some kind of factory method. Then instead of creating all promises upfront, you just create only one promise when you need it, wait until it is resolved and after it continue in same behaviour.

async function doAllSequentually(fnPromiseArr) {  for (let i=0; i < fnPromiseArr.length; i++) {    const val = await fnPromiseArr[i]();    console.log(val);  }}
function createFnPromise(val) { return () => new Promise(resolve => resolve(val));}
const arr = [];for (let j=0; j < 10; j++) { arr.push(createFnPromise(Math.random()));}
doAllSequentually(arr).then(() => console.log('finished'));

Parallel operations with Promise.all?

It's because your Promises are blocking and synchronous! Try something with a timeout instead of a synchronous loop:

    function randomResolve(name) {
return new Promise(resolve => setTimeout(() => {
console.log(name);
resolve();
}, 100 * Math.random()));
}

Promise.all([
randomResolve(1),
randomResolve(2),
randomResolve(3),
randomResolve(4),
])
.then(function(){
console.log("All Done!")
})


Related Topics



Leave a reply



Submit