Jaya
Jaya

Reputation: 3911

Promise.all.then is executed before the individual promises are completed

The following sample code represents what am trying to do, and am stumped as to why the console.log inside the Promises.all.then() is completed before even the individual promises are completed. I am thinking that the map statement has something to do with it , may be, but am unsure.

My intention of using a map was to collect all successes and or failures and notify the user later on bulk operations.

var requests = []; var success=[]; var failures = [];

requests.push(new Promise((resolve, reject) => setTimeout(() => resolve("foo success"), 2000)));
requests.push(new Promise((resolve, reject) => setTimeout(() => reject("bar failure"), 1000)));
requests.push(new Promise((resolve, reject) => setTimeout(() => resolve("foo2 success"), 2000)));
requests.push(new Promise((resolve, reject) => setTimeout(() => reject("bar2 failure"), 1000)));

Promise.all(requests.map(p => {
    p.then(r => {
        console.log(r)
        success.push(r);
    });
    p.catch((e) => { console.log(e); failures.push(e); });
})).then(function () { console.log("ALL promises completed")})

May i know what is wrong with the above code? Am i not implementing the promises as intended.?

Upvotes: 0

Views: 289

Answers (3)

Jacob
Jacob

Reputation: 78850

It's because your requests.map(...) callback doesn't return anything, so you're mapping the Promises to undefined values. Therefore, you're awaiting an array of undefined values with the Promise.all call. Change to the following:

Promise.all(requests.map(p => {
    p.then(r => {
      console.log(r)
      console.log("POSTed a record successfuly");
      success.push(r);
    });
    p.catch((e) => { console.log(e); failures.push(e); });
    return p;
})).then(function () { console.log("POSTED ALL")})

Update:

As @JoeFrambach pointed out, if you want the Promise.all to contain the contents of the original requests Promises, you'll want to return the original Promises. Since that's most likely what you want to do, I've updated my answer.

Upvotes: 3

ashish singh
ashish singh

Reputation: 6904

just return promise from your map callback function

var requests = []; var success=[]; var failures = [];

requests.push(new Promise((resolve, reject) => setTimeout(() => resolve("foo success"), 2000)));
requests.push(new Promise((resolve, reject) => setTimeout(() => reject("bar failure"), 1000)));
requests.push(new Promise((resolve, reject) => setTimeout(() => resolve("foo2 success"), 2000)));
requests.push(new Promise((resolve, reject) => setTimeout(() => reject("bar2 failure"), 1000)));

Promise.all(requests.map(p => {
    p.then(r => {
        console.log(r)
        success.push(r);
    });
    p.catch((e) => { console.log(e); failures.push(e); });
    return p; // ADD THIS LINE
})).then(function () { console.log("ALL promises completed")})
   .catch(function() {console.log("FAILED PROMISE ALL")});

Upvotes: 1

Shubham Gupta
Shubham Gupta

Reputation: 2646

You need to return a promise within .map function. Within .map function make last line as return p.

Promise all expects array of promises. You are returning array of undefined from map function so it immediately gets resolved.

Upvotes: 0

Related Questions