Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is my array of Promises running before calling Promise.all()?

I am trying to create an array of Promises, then resolve them with Promise.all(). I am using got, which returns a promise.

My code works, but I don't fully understand how. Here it is:

const got = require('got');

const url = 'myUrl';
const params = ['param1', 'param2', 'param3'];

let promiseArray = [];
for (param of params) {
    promiseArray.push(got(url + param));
}

// Inspect the promises
for (promise of promiseArray) {
    console.log(JSON.stringify(promise));
    // Output: promise: {"_pending":true,"_canceled":false,"_promise":{}}
}

Promise.all(promiseArray).then((results) => {
     // Operate on results - works just fine
}).catch((e) => {
    // Error handling logic
});

What throws me off is that the Promises are marked as "pending" when I add them into the array, which means they have already started.

I would think that they should lie inactive in promiseArray, and Promise.all(promiseArray) would both start them and resolve them.

Does this mean I am starting them twice?

like image 370
alexcs Avatar asked Dec 03 '17 19:12

alexcs


People also ask

Does promise all wait for all promises?

all() will reject immediately upon any of the input promises rejecting. In comparison, the promise returned by Promise. allSettled() will wait for all input promises to complete, regardless of whether or not one rejects.

Does promise all resolve promises in order?

Here, Promise. all() method is the order of the maintained promises. The first promise in the array will get resolved to the first element of the output array, the second promise will be a second element in the output array and so on.

Does promise all run sequentially?

all() method executed by taking promises as input in the single array and executing them sequentially.


Video Answer


2 Answers

You're not starting them twice. Promises start running as soon as they're created - or as soon as the JS engine finds enough resources to start them. You have no control on when they actually start.

All Promise.all() does is wait for all of them to settle (resolve or reject). Promise.all() does not interfere with nor influence the order/timing of execution of the promise itself.

like image 106
Arash Motamedi Avatar answered Oct 16 '22 02:10

Arash Motamedi


Promises don't run at all. They are simply a notification system for communicating when asynchronous operations are complete.

So, as soon as you ran this:

promiseArray.push(got(url + param));

Your asynchronous operation inside of got() is already started and when it finishes, it will communicate that back through the promise.

All Promise.all() does is monitor all the promises and tell you when the first one rejects or when all of them have completed successfully. It does not "control" the async operations in any way. Instead, you start the async operations and they communicate back through the promises. You control when you started the async operations and the async operations then run themselves from then on.


If you break down your code a bit into pieces, here's what happens in each piece:

let promiseArray = [];
for (param of params) {
    promiseArray.push(got(url + param));
}

This calls got() a bunch of times starting whatever async operation is in that function. got() presumably returns a promise object which is then put into your promiseArray. So, at this point, the async operations are all started already and running on their own.

// Inspect the promises
for (promise of promiseArray) {
    console.log(JSON.stringify(promise));
    // Output: promise: {"_pending":true,"_canceled":false,"_promise":{}}
}

This loop, just looks at all the promises to see if any of them might already be resolved, though one would not expect them to be because their underlying async operations were just started in the prior loop.

Promise.all(promiseArray).then((results) => {
     // Operate on results - works just fine
}).catch((e) => {
    // Error handling logic
});

Then, with Promise.all(), you're just asking to monitor the array of promises so it will tell you when either there's a rejected promise or when all of them complete successfully.

like image 32
jfriend00 Avatar answered Oct 16 '22 03:10

jfriend00