Wait until all ES6 promises complete, even rejected promises





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







298















Let's say I have a set of promises that are making network requests, of which one will fail:



// http://does-not-exist will throw a TypeError
var arr = [ fetch('index.html'), fetch('http://does-not-exist') ]

Promise.all(arr)
.then(res => console.log('success', res))
.catch(err => console.log('error', err)) // This is executed


Let's say I want to wait until all of these have finished, regardless of if one has failed. There might be a network error for a resource that I can live without, but which if I can get, I want before I proceed. I want to handle network failures gracefully.



Since Promises.all doesn't leave any room for this, what is the recommended pattern for handling this, without using a promises library?










share|improve this question

























  • What should be returned in resulting array for promises that rejected?

    – Kuba Wyrostek
    Jul 15 '15 at 8:07






  • 6





    ES6 promises support no such method (and are currently apparently slower than Bluebird). In addition, not all browsers or engines support them just yet. I would strongly recommend using Bluebird, which comes with allSettled which satisfies your need without you having to roll your own.

    – Dan Pantry
    Jul 15 '15 at 8:10













  • @KubaWyrostek I think you bring up the reason Promise.all doesn't have this behavior, which I think makes sense. This isn't how it works, but an alternative view would be to say Promise.all should return a special promise that never fails--and you would get the error that was thrown as the argument representing the failed promise.

    – Nathan Hagen
    Jul 15 '15 at 19:05






  • 3





    To expand on this, I'd like a version of Promise.all that resolves if one or more resolved, but rejects if all failed.

    – koga73
    Sep 1 '17 at 4:02






  • 1





    @Coli: Hmm, I don't think so. Promise.all will reject as soon as any one promise rejects, so your proposed idiom does not guarantee that all promises are settled.

    – Jörg W Mittag
    Oct 28 '18 at 21:49


















298















Let's say I have a set of promises that are making network requests, of which one will fail:



// http://does-not-exist will throw a TypeError
var arr = [ fetch('index.html'), fetch('http://does-not-exist') ]

Promise.all(arr)
.then(res => console.log('success', res))
.catch(err => console.log('error', err)) // This is executed


Let's say I want to wait until all of these have finished, regardless of if one has failed. There might be a network error for a resource that I can live without, but which if I can get, I want before I proceed. I want to handle network failures gracefully.



Since Promises.all doesn't leave any room for this, what is the recommended pattern for handling this, without using a promises library?










share|improve this question

























  • What should be returned in resulting array for promises that rejected?

    – Kuba Wyrostek
    Jul 15 '15 at 8:07






  • 6





    ES6 promises support no such method (and are currently apparently slower than Bluebird). In addition, not all browsers or engines support them just yet. I would strongly recommend using Bluebird, which comes with allSettled which satisfies your need without you having to roll your own.

    – Dan Pantry
    Jul 15 '15 at 8:10













  • @KubaWyrostek I think you bring up the reason Promise.all doesn't have this behavior, which I think makes sense. This isn't how it works, but an alternative view would be to say Promise.all should return a special promise that never fails--and you would get the error that was thrown as the argument representing the failed promise.

    – Nathan Hagen
    Jul 15 '15 at 19:05






  • 3





    To expand on this, I'd like a version of Promise.all that resolves if one or more resolved, but rejects if all failed.

    – koga73
    Sep 1 '17 at 4:02






  • 1





    @Coli: Hmm, I don't think so. Promise.all will reject as soon as any one promise rejects, so your proposed idiom does not guarantee that all promises are settled.

    – Jörg W Mittag
    Oct 28 '18 at 21:49














298












298








298


94






Let's say I have a set of promises that are making network requests, of which one will fail:



// http://does-not-exist will throw a TypeError
var arr = [ fetch('index.html'), fetch('http://does-not-exist') ]

Promise.all(arr)
.then(res => console.log('success', res))
.catch(err => console.log('error', err)) // This is executed


Let's say I want to wait until all of these have finished, regardless of if one has failed. There might be a network error for a resource that I can live without, but which if I can get, I want before I proceed. I want to handle network failures gracefully.



Since Promises.all doesn't leave any room for this, what is the recommended pattern for handling this, without using a promises library?










share|improve this question
















Let's say I have a set of promises that are making network requests, of which one will fail:



// http://does-not-exist will throw a TypeError
var arr = [ fetch('index.html'), fetch('http://does-not-exist') ]

Promise.all(arr)
.then(res => console.log('success', res))
.catch(err => console.log('error', err)) // This is executed


Let's say I want to wait until all of these have finished, regardless of if one has failed. There might be a network error for a resource that I can live without, but which if I can get, I want before I proceed. I want to handle network failures gracefully.



Since Promises.all doesn't leave any room for this, what is the recommended pattern for handling this, without using a promises library?







javascript promise es6-promise






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 22 at 20:42









jamix

3,68032128




3,68032128










asked Jul 15 '15 at 7:53









Nathan HagenNathan Hagen

6,18232031




6,18232031













  • What should be returned in resulting array for promises that rejected?

    – Kuba Wyrostek
    Jul 15 '15 at 8:07






  • 6





    ES6 promises support no such method (and are currently apparently slower than Bluebird). In addition, not all browsers or engines support them just yet. I would strongly recommend using Bluebird, which comes with allSettled which satisfies your need without you having to roll your own.

    – Dan Pantry
    Jul 15 '15 at 8:10













  • @KubaWyrostek I think you bring up the reason Promise.all doesn't have this behavior, which I think makes sense. This isn't how it works, but an alternative view would be to say Promise.all should return a special promise that never fails--and you would get the error that was thrown as the argument representing the failed promise.

    – Nathan Hagen
    Jul 15 '15 at 19:05






  • 3





    To expand on this, I'd like a version of Promise.all that resolves if one or more resolved, but rejects if all failed.

    – koga73
    Sep 1 '17 at 4:02






  • 1





    @Coli: Hmm, I don't think so. Promise.all will reject as soon as any one promise rejects, so your proposed idiom does not guarantee that all promises are settled.

    – Jörg W Mittag
    Oct 28 '18 at 21:49



















  • What should be returned in resulting array for promises that rejected?

    – Kuba Wyrostek
    Jul 15 '15 at 8:07






  • 6





    ES6 promises support no such method (and are currently apparently slower than Bluebird). In addition, not all browsers or engines support them just yet. I would strongly recommend using Bluebird, which comes with allSettled which satisfies your need without you having to roll your own.

    – Dan Pantry
    Jul 15 '15 at 8:10













  • @KubaWyrostek I think you bring up the reason Promise.all doesn't have this behavior, which I think makes sense. This isn't how it works, but an alternative view would be to say Promise.all should return a special promise that never fails--and you would get the error that was thrown as the argument representing the failed promise.

    – Nathan Hagen
    Jul 15 '15 at 19:05






  • 3





    To expand on this, I'd like a version of Promise.all that resolves if one or more resolved, but rejects if all failed.

    – koga73
    Sep 1 '17 at 4:02






  • 1





    @Coli: Hmm, I don't think so. Promise.all will reject as soon as any one promise rejects, so your proposed idiom does not guarantee that all promises are settled.

    – Jörg W Mittag
    Oct 28 '18 at 21:49

















What should be returned in resulting array for promises that rejected?

– Kuba Wyrostek
Jul 15 '15 at 8:07





What should be returned in resulting array for promises that rejected?

– Kuba Wyrostek
Jul 15 '15 at 8:07




6




6





ES6 promises support no such method (and are currently apparently slower than Bluebird). In addition, not all browsers or engines support them just yet. I would strongly recommend using Bluebird, which comes with allSettled which satisfies your need without you having to roll your own.

– Dan Pantry
Jul 15 '15 at 8:10







ES6 promises support no such method (and are currently apparently slower than Bluebird). In addition, not all browsers or engines support them just yet. I would strongly recommend using Bluebird, which comes with allSettled which satisfies your need without you having to roll your own.

– Dan Pantry
Jul 15 '15 at 8:10















@KubaWyrostek I think you bring up the reason Promise.all doesn't have this behavior, which I think makes sense. This isn't how it works, but an alternative view would be to say Promise.all should return a special promise that never fails--and you would get the error that was thrown as the argument representing the failed promise.

– Nathan Hagen
Jul 15 '15 at 19:05





@KubaWyrostek I think you bring up the reason Promise.all doesn't have this behavior, which I think makes sense. This isn't how it works, but an alternative view would be to say Promise.all should return a special promise that never fails--and you would get the error that was thrown as the argument representing the failed promise.

– Nathan Hagen
Jul 15 '15 at 19:05




3




3





To expand on this, I'd like a version of Promise.all that resolves if one or more resolved, but rejects if all failed.

– koga73
Sep 1 '17 at 4:02





To expand on this, I'd like a version of Promise.all that resolves if one or more resolved, but rejects if all failed.

– koga73
Sep 1 '17 at 4:02




1




1





@Coli: Hmm, I don't think so. Promise.all will reject as soon as any one promise rejects, so your proposed idiom does not guarantee that all promises are settled.

– Jörg W Mittag
Oct 28 '18 at 21:49





@Coli: Hmm, I don't think so. Promise.all will reject as soon as any one promise rejects, so your proposed idiom does not guarantee that all promises are settled.

– Jörg W Mittag
Oct 28 '18 at 21:49












15 Answers
15






active

oldest

votes


















237














Sure, you just need a reflect:



const reflect = p => p.then(v => ({v, status: "fulfilled" }),
e => ({e, status: "rejected" }));

reflect(promise).then((v => {
console.log(v.status);
});


Or with ES5:



function reflect(promise){
return promise.then(function(v){ return {v:v, status: "resolved" }},
function(e){ return {e:e, status: "rejected" }});
}


reflect(promise).then(function(v){
console.log(v.status);
});


Or in your example:



var arr = [ fetch('index.html'), fetch('http://does-not-exist') ]

Promise.all(arr.map(reflect)).then(function(results){
var success = results.filter(x => x.status === "resolved");
});





share|improve this answer





















  • 3





    I think this is a great solution. Can you amend it to include a simpler syntax? The crux of the issue is that if you want to handle errors in sub-promises, you should catch them and return the error. So for example: gist.github.com/nhagen/a1d36b39977822c224b8

    – Nathan Hagen
    Jul 15 '15 at 17:20








  • 1





    Simpler syntax? I don't understand what you mean.

    – Benjamin Gruenbaum
    Jul 15 '15 at 17:32






  • 3





    @NathanHagen it lets you figure out what rejected and what fulfilled and extracts the problem to a reusable operator.

    – Benjamin Gruenbaum
    Jul 15 '15 at 19:14






  • 4





    In response to my own issue I have created the following npm package: github.com/Bucabug/promise-reflect npmjs.com/package/promise-reflect

    – SamF
    Oct 11 '16 at 7:44








  • 2





    I ran into this issue a while ago and I created this npm package for it: npmjs.com/package/promise-all-soft-fail

    – velocity_distance
    Nov 28 '16 at 22:40



















198














Similar answer, but more idiomatic for ES6 perhaps:






const a = Promise.resolve(1);
const b = Promise.reject(new Error(2));
const c = Promise.resolve(3);

Promise.all([a, b, c].map(p => p.catch(e => e)))
.then(results => console.log(results)) // 1,Error: 2,3
.catch(e => console.log(e));


const console = { log: msg => div.innerHTML += msg + "<br>"};

<div id="div"></div>





Depending on the type(s) of values returned, errors can often be distinguished easily enough (e.g. use undefined for "don't care", typeof for plain non-object values, result.message, result.toString().startsWith("Error:") etc.)






share|improve this answer





















  • 3





    @jib saved my day. Best approach.

    – kushdilip
    Nov 25 '16 at 6:39






  • 1





    @KarlBateman I think you're confused. The order functions resolve or reject in don't matter here since the .map(p => p.catch(e => e)) part turns all rejections into resolved values, so Promise.all still waits for everything to finish whether individual functions resolve or reject, regardless of how long they take. Try it.

    – jib
    Dec 21 '16 at 15:44








  • 20





    .catch(e => console.log(e)); is never called because this never fails

    – bfred.it
    Mar 2 '17 at 11:31






  • 3





    @bfred.it That's correct. Though terminating promise chains with catch is generally good practice IMHO.

    – jib
    Mar 2 '17 at 15:11






  • 2





    @SuhailGupta It catches the error e and returns it as a regular (success) value. Same as p.catch(function(e) { return e; }) only shorter. return is implicit.

    – jib
    Mar 21 '17 at 4:54





















56














Benjamin's answer offers a great abstraction for solving this issue, but I was hoping for a less abstracted solution. The explicit way to to resolve this issue is to simply call .catch on the internal promises, and return the error from their callback.



let a = new Promise((res, rej) => res('Resolved!')),
b = new Promise((res, rej) => rej('Rejected!')),
c = a.catch(e => { console.log('"a" failed.'); return e; }),
d = b.catch(e => { console.log('"b" failed.'); return e; });

Promise.all([c, d])
.then(result => console.log('Then', result)) // Then ["Resolved!", "Rejected!"]
.catch(err => console.log('Catch', err));

Promise.all([a.catch(e => e), b.catch(e => e)])
.then(result => console.log('Then', result)) // Then ["Resolved!", "Rejected!"]
.catch(err => console.log('Catch', err));




Taking this one step further, you could write a generic catch handler that looks like this:



const catchHandler = error => ({ payload: error, resolved: false });


then you can do



> Promise.all([a, b].map(promise => promise.catch(catchHandler))
.then(results => console.log(results))
.catch(() => console.log('Promise.all failed'))
< [ 'Resolved!', { payload: Promise, resolved: false } ]


The problem with this is that the caught values will have a different interface than the non-caught values, so to clean this up you might do something like:



const successHandler = result => ({ payload: result, resolved: true });


So now you can do this:



> Promise.all([a, b].map(result => result.then(successHandler).catch(catchHandler))
.then(results => console.log(results.filter(result => result.resolved))
.catch(() => console.log('Promise.all failed'))
< [ 'Resolved!' ]


Then to keep it DRY, you get to Benjamin's answer:



const reflect = promise => promise
.then(successHandler)
.catch(catchHander)


where it now looks like



> Promise.all([a, b].map(result => result.then(successHandler).catch(catchHandler))
.then(results => console.log(results.filter(result => result.resolved))
.catch(() => console.log('Promise.all failed'))
< [ 'Resolved!' ]




The benefits of the second solution are that its abstracted and DRY. The downside is you have more code, and you have to remember to reflect all your promises to make things consistent.



I would characterize my solution as explicit and KISS, but indeed less robust. The interface doesn't guarantee that you know exactly whether the promise succeeded or failed.



For example you might have this:



const a = Promise.resolve(new Error('Not beaking, just bad'));
const b = Promise.reject(new Error('This actually didnt work'));


This won't get caught by a.catch, so



> Promise.all([a, b].map(promise => promise.catch(e => e))
.then(results => console.log(results))
< [ Error, Error ]


There's no way to tell which one was fatal and which was wasn't. If that's important then you're going to want to enforce and interface that tracks whether it was successful or not (which reflect does).



If you just want to handle errors gracefully, then you can just treat errors as undefined values:



> Promise.all([a.catch(() => undefined), b.catch(() => undefined)])
.then((results) => console.log('Known values: ', results.filter(x => typeof x !== 'undefined')))
< [ 'Resolved!' ]


In my case, I don't need to know the error or how it failed--I just care whether I have the value or not. I'll let the function that generates the promise worry about logging the specific error.



const apiMethod = () => fetch()
.catch(error => {
console.log(error.message);
throw error;
});


That way, the rest of the application can ignore its error if it wants, and treat it as an undefined value if it wants.



I want my high level functions to fail safely and not worry about the details on why its dependencies failed, and I also prefer KISS to DRY when I have to make that tradeoff--which is ultimately why I opted to not use reflect.






share|improve this answer





















  • 1





    @Benjamin I think @Nathan's solution is very straightforward and idiomatic for Promises. While your reflect improves code reuse, it also establishes another level of abstraction. Since Nathan's answer has so far only received a fraction of upvotes compared to yours, I wonder whether this is an indication of an issue with his solution, which I haven't recognized yet.

    – user6445533
    Jul 9 '16 at 10:54








  • 2





    @LUH3417 this solution is conceptually less sound since it treats errors as values and does not separate errors from non-errors. For example if one of the promises resolves legitimately to a value that can be thrown (which is entirely possible) this breaks quite badly.

    – Benjamin Gruenbaum
    Aug 2 '16 at 14:25






  • 2





    @BenjaminGruenbaum So for example, new Promise((res, rej) => res(new Error('Legitimate error')) would not be distinguishable from new Promise(((res, rej) => rej(new Error('Illegitimate error'))? Or further, you wouldn't be able to filter by x.status? I'll add this point to my answer so the difference is more clear

    – Nathan Hagen
    Aug 2 '16 at 15:53






  • 2





    The reason this is a poor idea is because it ties the Promise implementation to a specific use case of only ever being used in a specific Promise.all() variant, it also then becomes incumbent on the Promise consumer to know that a specific promise won't reject but will swallow it's errors. In fact the reflect() method could be made less 'abstract' and more explicit by calling it PromiseEvery(promises).then(...).The complexity of the answer above compared to Benjamin's should say much about this solution.

    – Neil
    Sep 28 '16 at 21:51





















9














I really like Benjamin's answer, and how he basically turns all promises into always-resolving-but-sometimes-with-error-as-a-result ones. :)

Here's my attempt at your request just in case you were looking for alternatives. This method simply treats errors as valid results, and is coded similar to Promise.all otherwise:



Promise.settle = function(promises) {
var results = ;
var done = promises.length;

return new Promise(function(resolve) {
function tryResolve(i, v) {
results[i] = v;
done = done - 1;
if (done == 0)
resolve(results);
}

for (var i=0; i<promises.length; i++)
promises[i].then(tryResolve.bind(null, i), tryResolve.bind(null, i));
if (done == 0)
resolve(results);
});
}





share|improve this answer


























  • This is typically called settle. We have that too in bluebird, I like reflect better but this is a viable solution for when you have this for an array.

    – Benjamin Gruenbaum
    Jul 15 '15 at 8:31






  • 2





    OK, settle will be a better name indeed. :)

    – Kuba Wyrostek
    Jul 15 '15 at 8:34











  • This looks a lot like the explicit promise construction antipattern. It should be noted that you never should write such a function yourself, but use the one your library supplies (OK, native ES6 is a bit meager).

    – Bergi
    Jul 16 '15 at 19:25













  • Could you please use the Promise constructor properly (and avoid that var resolve thingy)?

    – Bergi
    Jul 16 '15 at 19:26











  • Bergi, feel free to alter the answer however you consider necessary.

    – Kuba Wyrostek
    Jul 16 '15 at 19:33



















4














var err;
Promise.all([
promiseOne().catch(function(error) { err = error;}),
promiseTwo().catch(function(error) { err = error;})
]).then(function() {
if (err) {
throw err;
}
});


The Promise.all will swallow any rejected promise and store the error in a variable, so it will return when all of the promises have resolved. Then you can re-throw the error out, or do whatever. In this way, I guess you would get out the last rejection instead of the first one.






share|improve this answer



















  • 1





    Seems like this could aggregate errs by making it an array and using err.push(error), so all errors could be bubbled up.

    – ps2goat
    Apr 6 '18 at 15:03



















4














I had the same problem and have solved it in the following way:



const fetch = (url) => {
return node-fetch(url)
.then(result => result.json())
.catch((e) => {
return new Promise((resolve) => setTimeout(() => resolve(fetch(url)), timeout));
});
};

tasks = [fetch(url1), fetch(url2) ....];

Promise.all(tasks).then(......)


In that case Promise.all will wait for every Promise will come into resolved or rejected state.



And having this solution we are "stopping catch execution" in a non-blocking way. In fact, we're not stopping anything, we just returning back the Promise in a pending state which returns another Promise when it's resolved after the timeout.






share|improve this answer


























  • But that invokes all promises at will when you run Promise.all. I'm looking for a way to listen for when all promises have been invoked, but not invoke them myself. Thanks.

    – SudoPlz
    Jan 3 '18 at 12:25













  • @SudoPlz the method all() does that, it waits for the fulfilment of all Promises or rejection at least one of it.

    – user1016265
    Jan 3 '18 at 20:46













  • that's true, but it doesn't just wait, it actually invokes/starts/fires up the process. If you wished to fire up the promises someplace else that wouldn't be possible, becase .all fires everything up.

    – SudoPlz
    Jan 3 '18 at 21:10













  • @SudoPlz hope this will change your opinion jsfiddle.net/d1z1vey5

    – user1016265
    Jan 4 '18 at 21:35






  • 2





    I stand corrected. Until now I thought Promises only run when someone invokes them (a.k.a a then or an .all call) but they run when created.

    – SudoPlz
    Jan 5 '18 at 0:23





















2














This should be consistent with how Q does it:



if(!Promise.allSettled) {
Promise.allSettled = function (promises) {
return Promise.all(promises.map(p => Promise.resolve(p).then(v => ({
state: 'fulfilled',
value: v,
}), r => ({
state: 'rejected',
reason: r,
}))));
};
}





share|improve this answer































    2














    Benjamin Gruenbaum answer is of course great,. But I can also see were Nathan Hagen point of view with the level of abstraction seem vague. Having short object properties like e & v don't help either, but of course that could be changed.



    In Javascript there is standard Error object, called Error,. Ideally you always throw an instance / descendant of this. The advantage is that you can do instanceof Error, and you know something is an error.



    So using this idea, here is my take on the problem.



    Basically catch the error, if the error is not of type Error, wrap the error inside an Error object. The resulting array will have either resolved values, or Error objects you can check on.



    The instanceof inside the catch, is in case you use some external library that maybe did reject("error"), instead of reject(new Error("error")).



    Of course you could have promises were you resolve an error, but in that case it would most likely make sense to treat as an error anyway, like the last example shows.



    Another advantage of doing it this, array destructing is kept simple.



    const [value1, value2] = PromiseAllCatch(promises);
    if (!(value1 instanceof Error)) console.log(value1);


    Instead of



    const [{v: value1, e: error1}, {v: value2, e: error2}] = Promise.all(reflect..
    if (!error1) { console.log(value1); }


    You could argue that the !error1 check is simpler than an instanceof, but your also having to destruct both v & e.






    function PromiseAllCatch(promises) {
    return Promise.all(promises.map(async m => {
    try {
    return await m;
    } catch(e) {
    if (e instanceof Error) return e;
    return new Error(e);
    }
    }));
    }


    async function test() {
    const ret = await PromiseAllCatch([
    (async () => "this is fine")(),
    (async () => {throw new Error("oops")})(),
    (async () => "this is ok")(),
    (async () => {throw "Still an error";})(),
    (async () => new Error("resolved Error"))(),
    ]);
    console.log(ret);
    console.log(ret.map(r =>
    r instanceof Error ? "error" : "ok"
    ).join(" : "));
    }

    test();








    share|improve this answer

































      0














      Here's my custom settledPromiseAll()



      const settledPromiseAll = function(promisesArray) {
      var savedError;

      const saveFirstError = function(error) {
      if (!savedError) savedError = error;
      };
      const handleErrors = function(value) {
      return Promise.resolve(value).catch(saveFirstError);
      };
      const allSettled = Promise.all(promisesArray.map(handleErrors));

      return allSettled.then(function(resolvedPromises) {
      if (savedError) throw savedError;
      return resolvedPromises;
      });
      };


      Compared to Promise.all




      • If all promises are resolved, it performs exactly as the standard one.


      • If one of more promises are rejected, it returns the first one rejected much the same as the standard one but unlike it waits for all promises to resolve/reject.



      For the brave we could change Promise.all():



      (function() {
      var stdAll = Promise.all;

      Promise.all = function(values, wait) {
      if(!wait)
      return stdAll.call(Promise, values);

      return settledPromiseAll(values);
      }
      })();


      CAREFUL. In general we never change built-ins, as it might break other unrelated JS libraries or clash with future changes to JS standards.



      My settledPromiseall is backward compatible with Promise.all and extends its functionality.



      People who are developing standards -- why not include this to a new Promise standard?






      share|improve this answer

































        0














        I think the following offers a slightly different approach... compare fn_fast_fail() with fn_slow_fail()... though the latter doesn't fail as such... you can check if one or both of a and b is an instance of Error and throw that Error if you want it to reach the catch block (e.g. if (b instanceof Error) { throw b; }) . See the jsfiddle.



        var p1 = new Promise((resolve, reject) => { 
        setTimeout(() => resolve('p1_delayed_resolvement'), 2000);
        });

        var p2 = new Promise((resolve, reject) => {
        reject(new Error('p2_immediate_rejection'));
        });

        var fn_fast_fail = async function () {
        try {
        var [a, b] = await Promise.all([p1, p2]);
        console.log(a); // "p1_delayed_resolvement"
        console.log(b); // "Error: p2_immediate_rejection"
        } catch (err) {
        console.log('ERROR:', err);
        }
        }

        var fn_slow_fail = async function () {
        try {
        var [a, b] = await Promise.all([
        p1.catch(error => { return error }),
        p2.catch(error => { return error })
        ]);
        console.log(a); // "p1_delayed_resolvement"
        console.log(b); // "Error: p2_immediate_rejection"
        } catch (err) {
        // we don't reach here unless you throw the error from the `try` block
        console.log('ERROR:', err);
        }
        }

        fn_fast_fail(); // fails immediately
        fn_slow_fail(); // waits for delayed promise to resolve





        share|improve this answer

































          -1














          I would do:



          var err = [fetch('index.html').then((success) => { return Promise.resolve(success); }).catch((e) => { return Promise.resolve(e); }),
          fetch('http://does-not-exist').then((success) => { return Promise.resolve(success); }).catch((e) => { return Promise.resolve(e); })];

          Promise.all(err)
          .then(function (res) { console.log('success', res) })
          .catch(function (err) { console.log('error', err) }) //never executed





          share|improve this answer































            -1














            You can execute your logic sequentially via synchronous executor nsynjs. It will pause on each promise, wait for resolution/rejection, and either assign resolve's result to data property, or throw an exception (for handling that you will need try/catch block). Here is an example:






            function synchronousCode() {
            function myFetch(url) {
            try {
            return window.fetch(url).data;
            }
            catch (e) {
            return {status: 'failed:'+e};
            };
            };
            var arr=[
            myFetch("https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"),
            myFetch("https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/NONEXISTANT.js"),
            myFetch("https://ajax.NONEXISTANT123.com/ajax/libs/jquery/2.0.0/NONEXISTANT.js")
            ];

            console.log('array is ready:',arr[0].status,arr[1].status,arr[2].status);
            };

            nsynjs.run(synchronousCode,{},function(){
            console.log('done');
            });

            <script src="https://rawgit.com/amaksr/nsynjs/master/nsynjs.js"></script>








            share|improve this answer

































              -1














              I've been using following codes since ES5.



              Promise.wait = function(promiseQueue){
              if( !Array.isArray(promiseQueue) ){
              return Promise.reject('Given parameter is not an array!');
              }

              if( promiseQueue.length === 0 ){
              return Promise.resolve();
              }

              return new Promise((resolve, reject) =>{
              let _pQueue=, _rQueue=, _readyCount=false;
              promiseQueue.forEach((_promise, idx) =>{
              // Create a status info object
              _rQueue.push({rejected:false, seq:idx, result:null});
              _pQueue.push(Promise.resolve(_promise));
              });

              _pQueue.forEach((_promise, idx)=>{
              let item = _rQueue[idx];
              _promise.then(
              (result)=>{
              item.resolved = true;
              item.result = result;
              },
              (error)=>{
              item.resolved = false;
              item.result = error;
              }
              ).then(()=>{
              _readyCount++;

              if ( _rQueue.length === _readyCount ) {
              let result = true;
              _rQueue.forEach((item)=>{result=result&&item.resolved;});
              (result?resolve:reject)(_rQueue);
              }
              });
              });
              });
              };


              The usage signature is just like Promise.all. The major difference is that Promise.wait will wait for all the promises to finish their jobs.






              share|improve this answer































                -1














                I know that this question has a lot of answers, and I'm sure must (if not all) are correct.
                However it was very hard for me to understand the logic/flow of these answers.



                So I looked at the Original Implementation on Promise.all(), and I tried to imitate that logic - with the exception of not stopping the execution if one Promise failed.



                  public promiseExecuteAll(promisesList: Promise<any> = ): Promise<{ data: any, isSuccess: boolean }>
                {
                let promise: Promise<{ data: any, isSuccess: boolean }>;

                if (promisesList.length)
                {
                const result: { data: any, isSuccess: boolean } = ;
                let count: number = 0;

                promise = new Promise<{ data: any, isSuccess: boolean }>((resolve, reject) =>
                {
                promisesList.forEach((currentPromise: Promise<any>, index: number) =>
                {
                currentPromise.then(
                (data) => // Success
                {
                result[index] = { data, isSuccess: true };
                if (promisesList.length <= ++count) { resolve(result); }
                },
                (data) => // Error
                {
                result[index] = { data, isSuccess: false };
                if (promisesList.length <= ++count) { resolve(result); }
                });
                });
                });
                }
                else
                {
                promise = Promise.resolve();
                }

                return promise;
                }


                Explanation:

                - Loop over the input promisesList and execute each Promise.

                - No matter if the Promise resolved or rejected: save the Promise's result in a result array according to the index. Save also the resolve/reject status (isSuccess).

                - Once all Promises completed, return one Promise with the result of all others.



                Example of use:



                const p1 = Promise.resolve("OK");
                const p2 = Promise.reject(new Error(":-("));
                const p3 = Promise.resolve(1000);

                promiseExecuteAll([p1, p2, p3]).then((data) => {
                data.forEach(value => console.log(`${ value.isSuccess ? 'Resolve' : 'Reject' } >> ${ value.data }`));
                });

                /* Output:
                Resolve >> OK
                Reject >> :-(
                Resolve >> 1000
                */





                share|improve this answer





















                • 1





                  Don't try to re-implement Promise.all yourself, there are too many things that will go wrong. Your version doesn't handle empty inputs for example.

                  – Bergi
                  Mar 8 at 14:04



















                -3














                I don't know which promise library you are using, but most have something like allSettled.



                Edit: Ok since you want to use plain ES6 without external libraries, there is no such method.



                In other words: You have to loop over your promises manually and resolve a new combined promise as soon as all promises are settled.






                share|improve this answer


























                • I've edited my question to clarify--Since ES6 comes with promises, I'd like to avoid using another library for what I would think is basic functionality. I guess a good place to get the answer from would be to copy the source from one of the promise libraries.

                  – Nathan Hagen
                  Jul 15 '15 at 8:05










                protected by Josh Crozier Dec 9 '18 at 5:26



                Thank you for your interest in this question.
                Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



                Would you like to answer one of these unanswered questions instead?














                15 Answers
                15






                active

                oldest

                votes








                15 Answers
                15






                active

                oldest

                votes









                active

                oldest

                votes






                active

                oldest

                votes









                237














                Sure, you just need a reflect:



                const reflect = p => p.then(v => ({v, status: "fulfilled" }),
                e => ({e, status: "rejected" }));

                reflect(promise).then((v => {
                console.log(v.status);
                });


                Or with ES5:



                function reflect(promise){
                return promise.then(function(v){ return {v:v, status: "resolved" }},
                function(e){ return {e:e, status: "rejected" }});
                }


                reflect(promise).then(function(v){
                console.log(v.status);
                });


                Or in your example:



                var arr = [ fetch('index.html'), fetch('http://does-not-exist') ]

                Promise.all(arr.map(reflect)).then(function(results){
                var success = results.filter(x => x.status === "resolved");
                });





                share|improve this answer





















                • 3





                  I think this is a great solution. Can you amend it to include a simpler syntax? The crux of the issue is that if you want to handle errors in sub-promises, you should catch them and return the error. So for example: gist.github.com/nhagen/a1d36b39977822c224b8

                  – Nathan Hagen
                  Jul 15 '15 at 17:20








                • 1





                  Simpler syntax? I don't understand what you mean.

                  – Benjamin Gruenbaum
                  Jul 15 '15 at 17:32






                • 3





                  @NathanHagen it lets you figure out what rejected and what fulfilled and extracts the problem to a reusable operator.

                  – Benjamin Gruenbaum
                  Jul 15 '15 at 19:14






                • 4





                  In response to my own issue I have created the following npm package: github.com/Bucabug/promise-reflect npmjs.com/package/promise-reflect

                  – SamF
                  Oct 11 '16 at 7:44








                • 2





                  I ran into this issue a while ago and I created this npm package for it: npmjs.com/package/promise-all-soft-fail

                  – velocity_distance
                  Nov 28 '16 at 22:40
















                237














                Sure, you just need a reflect:



                const reflect = p => p.then(v => ({v, status: "fulfilled" }),
                e => ({e, status: "rejected" }));

                reflect(promise).then((v => {
                console.log(v.status);
                });


                Or with ES5:



                function reflect(promise){
                return promise.then(function(v){ return {v:v, status: "resolved" }},
                function(e){ return {e:e, status: "rejected" }});
                }


                reflect(promise).then(function(v){
                console.log(v.status);
                });


                Or in your example:



                var arr = [ fetch('index.html'), fetch('http://does-not-exist') ]

                Promise.all(arr.map(reflect)).then(function(results){
                var success = results.filter(x => x.status === "resolved");
                });





                share|improve this answer





















                • 3





                  I think this is a great solution. Can you amend it to include a simpler syntax? The crux of the issue is that if you want to handle errors in sub-promises, you should catch them and return the error. So for example: gist.github.com/nhagen/a1d36b39977822c224b8

                  – Nathan Hagen
                  Jul 15 '15 at 17:20








                • 1





                  Simpler syntax? I don't understand what you mean.

                  – Benjamin Gruenbaum
                  Jul 15 '15 at 17:32






                • 3





                  @NathanHagen it lets you figure out what rejected and what fulfilled and extracts the problem to a reusable operator.

                  – Benjamin Gruenbaum
                  Jul 15 '15 at 19:14






                • 4





                  In response to my own issue I have created the following npm package: github.com/Bucabug/promise-reflect npmjs.com/package/promise-reflect

                  – SamF
                  Oct 11 '16 at 7:44








                • 2





                  I ran into this issue a while ago and I created this npm package for it: npmjs.com/package/promise-all-soft-fail

                  – velocity_distance
                  Nov 28 '16 at 22:40














                237












                237








                237







                Sure, you just need a reflect:



                const reflect = p => p.then(v => ({v, status: "fulfilled" }),
                e => ({e, status: "rejected" }));

                reflect(promise).then((v => {
                console.log(v.status);
                });


                Or with ES5:



                function reflect(promise){
                return promise.then(function(v){ return {v:v, status: "resolved" }},
                function(e){ return {e:e, status: "rejected" }});
                }


                reflect(promise).then(function(v){
                console.log(v.status);
                });


                Or in your example:



                var arr = [ fetch('index.html'), fetch('http://does-not-exist') ]

                Promise.all(arr.map(reflect)).then(function(results){
                var success = results.filter(x => x.status === "resolved");
                });





                share|improve this answer















                Sure, you just need a reflect:



                const reflect = p => p.then(v => ({v, status: "fulfilled" }),
                e => ({e, status: "rejected" }));

                reflect(promise).then((v => {
                console.log(v.status);
                });


                Or with ES5:



                function reflect(promise){
                return promise.then(function(v){ return {v:v, status: "resolved" }},
                function(e){ return {e:e, status: "rejected" }});
                }


                reflect(promise).then(function(v){
                console.log(v.status);
                });


                Or in your example:



                var arr = [ fetch('index.html'), fetch('http://does-not-exist') ]

                Promise.all(arr.map(reflect)).then(function(results){
                var success = results.filter(x => x.status === "resolved");
                });






                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Jun 13 '18 at 10:02

























                answered Jul 15 '15 at 8:07









                Benjamin GruenbaumBenjamin Gruenbaum

                193k65408442




                193k65408442








                • 3





                  I think this is a great solution. Can you amend it to include a simpler syntax? The crux of the issue is that if you want to handle errors in sub-promises, you should catch them and return the error. So for example: gist.github.com/nhagen/a1d36b39977822c224b8

                  – Nathan Hagen
                  Jul 15 '15 at 17:20








                • 1





                  Simpler syntax? I don't understand what you mean.

                  – Benjamin Gruenbaum
                  Jul 15 '15 at 17:32






                • 3





                  @NathanHagen it lets you figure out what rejected and what fulfilled and extracts the problem to a reusable operator.

                  – Benjamin Gruenbaum
                  Jul 15 '15 at 19:14






                • 4





                  In response to my own issue I have created the following npm package: github.com/Bucabug/promise-reflect npmjs.com/package/promise-reflect

                  – SamF
                  Oct 11 '16 at 7:44








                • 2





                  I ran into this issue a while ago and I created this npm package for it: npmjs.com/package/promise-all-soft-fail

                  – velocity_distance
                  Nov 28 '16 at 22:40














                • 3





                  I think this is a great solution. Can you amend it to include a simpler syntax? The crux of the issue is that if you want to handle errors in sub-promises, you should catch them and return the error. So for example: gist.github.com/nhagen/a1d36b39977822c224b8

                  – Nathan Hagen
                  Jul 15 '15 at 17:20








                • 1





                  Simpler syntax? I don't understand what you mean.

                  – Benjamin Gruenbaum
                  Jul 15 '15 at 17:32






                • 3





                  @NathanHagen it lets you figure out what rejected and what fulfilled and extracts the problem to a reusable operator.

                  – Benjamin Gruenbaum
                  Jul 15 '15 at 19:14






                • 4





                  In response to my own issue I have created the following npm package: github.com/Bucabug/promise-reflect npmjs.com/package/promise-reflect

                  – SamF
                  Oct 11 '16 at 7:44








                • 2





                  I ran into this issue a while ago and I created this npm package for it: npmjs.com/package/promise-all-soft-fail

                  – velocity_distance
                  Nov 28 '16 at 22:40








                3




                3





                I think this is a great solution. Can you amend it to include a simpler syntax? The crux of the issue is that if you want to handle errors in sub-promises, you should catch them and return the error. So for example: gist.github.com/nhagen/a1d36b39977822c224b8

                – Nathan Hagen
                Jul 15 '15 at 17:20







                I think this is a great solution. Can you amend it to include a simpler syntax? The crux of the issue is that if you want to handle errors in sub-promises, you should catch them and return the error. So for example: gist.github.com/nhagen/a1d36b39977822c224b8

                – Nathan Hagen
                Jul 15 '15 at 17:20






                1




                1





                Simpler syntax? I don't understand what you mean.

                – Benjamin Gruenbaum
                Jul 15 '15 at 17:32





                Simpler syntax? I don't understand what you mean.

                – Benjamin Gruenbaum
                Jul 15 '15 at 17:32




                3




                3





                @NathanHagen it lets you figure out what rejected and what fulfilled and extracts the problem to a reusable operator.

                – Benjamin Gruenbaum
                Jul 15 '15 at 19:14





                @NathanHagen it lets you figure out what rejected and what fulfilled and extracts the problem to a reusable operator.

                – Benjamin Gruenbaum
                Jul 15 '15 at 19:14




                4




                4





                In response to my own issue I have created the following npm package: github.com/Bucabug/promise-reflect npmjs.com/package/promise-reflect

                – SamF
                Oct 11 '16 at 7:44







                In response to my own issue I have created the following npm package: github.com/Bucabug/promise-reflect npmjs.com/package/promise-reflect

                – SamF
                Oct 11 '16 at 7:44






                2




                2





                I ran into this issue a while ago and I created this npm package for it: npmjs.com/package/promise-all-soft-fail

                – velocity_distance
                Nov 28 '16 at 22:40





                I ran into this issue a while ago and I created this npm package for it: npmjs.com/package/promise-all-soft-fail

                – velocity_distance
                Nov 28 '16 at 22:40













                198














                Similar answer, but more idiomatic for ES6 perhaps:






                const a = Promise.resolve(1);
                const b = Promise.reject(new Error(2));
                const c = Promise.resolve(3);

                Promise.all([a, b, c].map(p => p.catch(e => e)))
                .then(results => console.log(results)) // 1,Error: 2,3
                .catch(e => console.log(e));


                const console = { log: msg => div.innerHTML += msg + "<br>"};

                <div id="div"></div>





                Depending on the type(s) of values returned, errors can often be distinguished easily enough (e.g. use undefined for "don't care", typeof for plain non-object values, result.message, result.toString().startsWith("Error:") etc.)






                share|improve this answer





















                • 3





                  @jib saved my day. Best approach.

                  – kushdilip
                  Nov 25 '16 at 6:39






                • 1





                  @KarlBateman I think you're confused. The order functions resolve or reject in don't matter here since the .map(p => p.catch(e => e)) part turns all rejections into resolved values, so Promise.all still waits for everything to finish whether individual functions resolve or reject, regardless of how long they take. Try it.

                  – jib
                  Dec 21 '16 at 15:44








                • 20





                  .catch(e => console.log(e)); is never called because this never fails

                  – bfred.it
                  Mar 2 '17 at 11:31






                • 3





                  @bfred.it That's correct. Though terminating promise chains with catch is generally good practice IMHO.

                  – jib
                  Mar 2 '17 at 15:11






                • 2





                  @SuhailGupta It catches the error e and returns it as a regular (success) value. Same as p.catch(function(e) { return e; }) only shorter. return is implicit.

                  – jib
                  Mar 21 '17 at 4:54


















                198














                Similar answer, but more idiomatic for ES6 perhaps:






                const a = Promise.resolve(1);
                const b = Promise.reject(new Error(2));
                const c = Promise.resolve(3);

                Promise.all([a, b, c].map(p => p.catch(e => e)))
                .then(results => console.log(results)) // 1,Error: 2,3
                .catch(e => console.log(e));


                const console = { log: msg => div.innerHTML += msg + "<br>"};

                <div id="div"></div>





                Depending on the type(s) of values returned, errors can often be distinguished easily enough (e.g. use undefined for "don't care", typeof for plain non-object values, result.message, result.toString().startsWith("Error:") etc.)






                share|improve this answer





















                • 3





                  @jib saved my day. Best approach.

                  – kushdilip
                  Nov 25 '16 at 6:39






                • 1





                  @KarlBateman I think you're confused. The order functions resolve or reject in don't matter here since the .map(p => p.catch(e => e)) part turns all rejections into resolved values, so Promise.all still waits for everything to finish whether individual functions resolve or reject, regardless of how long they take. Try it.

                  – jib
                  Dec 21 '16 at 15:44








                • 20





                  .catch(e => console.log(e)); is never called because this never fails

                  – bfred.it
                  Mar 2 '17 at 11:31






                • 3





                  @bfred.it That's correct. Though terminating promise chains with catch is generally good practice IMHO.

                  – jib
                  Mar 2 '17 at 15:11






                • 2





                  @SuhailGupta It catches the error e and returns it as a regular (success) value. Same as p.catch(function(e) { return e; }) only shorter. return is implicit.

                  – jib
                  Mar 21 '17 at 4:54
















                198












                198








                198







                Similar answer, but more idiomatic for ES6 perhaps:






                const a = Promise.resolve(1);
                const b = Promise.reject(new Error(2));
                const c = Promise.resolve(3);

                Promise.all([a, b, c].map(p => p.catch(e => e)))
                .then(results => console.log(results)) // 1,Error: 2,3
                .catch(e => console.log(e));


                const console = { log: msg => div.innerHTML += msg + "<br>"};

                <div id="div"></div>





                Depending on the type(s) of values returned, errors can often be distinguished easily enough (e.g. use undefined for "don't care", typeof for plain non-object values, result.message, result.toString().startsWith("Error:") etc.)






                share|improve this answer















                Similar answer, but more idiomatic for ES6 perhaps:






                const a = Promise.resolve(1);
                const b = Promise.reject(new Error(2));
                const c = Promise.resolve(3);

                Promise.all([a, b, c].map(p => p.catch(e => e)))
                .then(results => console.log(results)) // 1,Error: 2,3
                .catch(e => console.log(e));


                const console = { log: msg => div.innerHTML += msg + "<br>"};

                <div id="div"></div>





                Depending on the type(s) of values returned, errors can often be distinguished easily enough (e.g. use undefined for "don't care", typeof for plain non-object values, result.message, result.toString().startsWith("Error:") etc.)






                const a = Promise.resolve(1);
                const b = Promise.reject(new Error(2));
                const c = Promise.resolve(3);

                Promise.all([a, b, c].map(p => p.catch(e => e)))
                .then(results => console.log(results)) // 1,Error: 2,3
                .catch(e => console.log(e));


                const console = { log: msg => div.innerHTML += msg + "<br>"};

                <div id="div"></div>





                const a = Promise.resolve(1);
                const b = Promise.reject(new Error(2));
                const c = Promise.resolve(3);

                Promise.all([a, b, c].map(p => p.catch(e => e)))
                .then(results => console.log(results)) // 1,Error: 2,3
                .catch(e => console.log(e));


                const console = { log: msg => div.innerHTML += msg + "<br>"};

                <div id="div"></div>






                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Jan 18 '18 at 13:34









                Dan Dascalescu

                70.1k22208280




                70.1k22208280










                answered Mar 20 '16 at 15:16









                jibjib

                22.1k64695




                22.1k64695








                • 3





                  @jib saved my day. Best approach.

                  – kushdilip
                  Nov 25 '16 at 6:39






                • 1





                  @KarlBateman I think you're confused. The order functions resolve or reject in don't matter here since the .map(p => p.catch(e => e)) part turns all rejections into resolved values, so Promise.all still waits for everything to finish whether individual functions resolve or reject, regardless of how long they take. Try it.

                  – jib
                  Dec 21 '16 at 15:44








                • 20





                  .catch(e => console.log(e)); is never called because this never fails

                  – bfred.it
                  Mar 2 '17 at 11:31






                • 3





                  @bfred.it That's correct. Though terminating promise chains with catch is generally good practice IMHO.

                  – jib
                  Mar 2 '17 at 15:11






                • 2





                  @SuhailGupta It catches the error e and returns it as a regular (success) value. Same as p.catch(function(e) { return e; }) only shorter. return is implicit.

                  – jib
                  Mar 21 '17 at 4:54
















                • 3





                  @jib saved my day. Best approach.

                  – kushdilip
                  Nov 25 '16 at 6:39






                • 1





                  @KarlBateman I think you're confused. The order functions resolve or reject in don't matter here since the .map(p => p.catch(e => e)) part turns all rejections into resolved values, so Promise.all still waits for everything to finish whether individual functions resolve or reject, regardless of how long they take. Try it.

                  – jib
                  Dec 21 '16 at 15:44








                • 20





                  .catch(e => console.log(e)); is never called because this never fails

                  – bfred.it
                  Mar 2 '17 at 11:31






                • 3





                  @bfred.it That's correct. Though terminating promise chains with catch is generally good practice IMHO.

                  – jib
                  Mar 2 '17 at 15:11






                • 2





                  @SuhailGupta It catches the error e and returns it as a regular (success) value. Same as p.catch(function(e) { return e; }) only shorter. return is implicit.

                  – jib
                  Mar 21 '17 at 4:54










                3




                3





                @jib saved my day. Best approach.

                – kushdilip
                Nov 25 '16 at 6:39





                @jib saved my day. Best approach.

                – kushdilip
                Nov 25 '16 at 6:39




                1




                1





                @KarlBateman I think you're confused. The order functions resolve or reject in don't matter here since the .map(p => p.catch(e => e)) part turns all rejections into resolved values, so Promise.all still waits for everything to finish whether individual functions resolve or reject, regardless of how long they take. Try it.

                – jib
                Dec 21 '16 at 15:44







                @KarlBateman I think you're confused. The order functions resolve or reject in don't matter here since the .map(p => p.catch(e => e)) part turns all rejections into resolved values, so Promise.all still waits for everything to finish whether individual functions resolve or reject, regardless of how long they take. Try it.

                – jib
                Dec 21 '16 at 15:44






                20




                20





                .catch(e => console.log(e)); is never called because this never fails

                – bfred.it
                Mar 2 '17 at 11:31





                .catch(e => console.log(e)); is never called because this never fails

                – bfred.it
                Mar 2 '17 at 11:31




                3




                3





                @bfred.it That's correct. Though terminating promise chains with catch is generally good practice IMHO.

                – jib
                Mar 2 '17 at 15:11





                @bfred.it That's correct. Though terminating promise chains with catch is generally good practice IMHO.

                – jib
                Mar 2 '17 at 15:11




                2




                2





                @SuhailGupta It catches the error e and returns it as a regular (success) value. Same as p.catch(function(e) { return e; }) only shorter. return is implicit.

                – jib
                Mar 21 '17 at 4:54







                @SuhailGupta It catches the error e and returns it as a regular (success) value. Same as p.catch(function(e) { return e; }) only shorter. return is implicit.

                – jib
                Mar 21 '17 at 4:54













                56














                Benjamin's answer offers a great abstraction for solving this issue, but I was hoping for a less abstracted solution. The explicit way to to resolve this issue is to simply call .catch on the internal promises, and return the error from their callback.



                let a = new Promise((res, rej) => res('Resolved!')),
                b = new Promise((res, rej) => rej('Rejected!')),
                c = a.catch(e => { console.log('"a" failed.'); return e; }),
                d = b.catch(e => { console.log('"b" failed.'); return e; });

                Promise.all([c, d])
                .then(result => console.log('Then', result)) // Then ["Resolved!", "Rejected!"]
                .catch(err => console.log('Catch', err));

                Promise.all([a.catch(e => e), b.catch(e => e)])
                .then(result => console.log('Then', result)) // Then ["Resolved!", "Rejected!"]
                .catch(err => console.log('Catch', err));




                Taking this one step further, you could write a generic catch handler that looks like this:



                const catchHandler = error => ({ payload: error, resolved: false });


                then you can do



                > Promise.all([a, b].map(promise => promise.catch(catchHandler))
                .then(results => console.log(results))
                .catch(() => console.log('Promise.all failed'))
                < [ 'Resolved!', { payload: Promise, resolved: false } ]


                The problem with this is that the caught values will have a different interface than the non-caught values, so to clean this up you might do something like:



                const successHandler = result => ({ payload: result, resolved: true });


                So now you can do this:



                > Promise.all([a, b].map(result => result.then(successHandler).catch(catchHandler))
                .then(results => console.log(results.filter(result => result.resolved))
                .catch(() => console.log('Promise.all failed'))
                < [ 'Resolved!' ]


                Then to keep it DRY, you get to Benjamin's answer:



                const reflect = promise => promise
                .then(successHandler)
                .catch(catchHander)


                where it now looks like



                > Promise.all([a, b].map(result => result.then(successHandler).catch(catchHandler))
                .then(results => console.log(results.filter(result => result.resolved))
                .catch(() => console.log('Promise.all failed'))
                < [ 'Resolved!' ]




                The benefits of the second solution are that its abstracted and DRY. The downside is you have more code, and you have to remember to reflect all your promises to make things consistent.



                I would characterize my solution as explicit and KISS, but indeed less robust. The interface doesn't guarantee that you know exactly whether the promise succeeded or failed.



                For example you might have this:



                const a = Promise.resolve(new Error('Not beaking, just bad'));
                const b = Promise.reject(new Error('This actually didnt work'));


                This won't get caught by a.catch, so



                > Promise.all([a, b].map(promise => promise.catch(e => e))
                .then(results => console.log(results))
                < [ Error, Error ]


                There's no way to tell which one was fatal and which was wasn't. If that's important then you're going to want to enforce and interface that tracks whether it was successful or not (which reflect does).



                If you just want to handle errors gracefully, then you can just treat errors as undefined values:



                > Promise.all([a.catch(() => undefined), b.catch(() => undefined)])
                .then((results) => console.log('Known values: ', results.filter(x => typeof x !== 'undefined')))
                < [ 'Resolved!' ]


                In my case, I don't need to know the error or how it failed--I just care whether I have the value or not. I'll let the function that generates the promise worry about logging the specific error.



                const apiMethod = () => fetch()
                .catch(error => {
                console.log(error.message);
                throw error;
                });


                That way, the rest of the application can ignore its error if it wants, and treat it as an undefined value if it wants.



                I want my high level functions to fail safely and not worry about the details on why its dependencies failed, and I also prefer KISS to DRY when I have to make that tradeoff--which is ultimately why I opted to not use reflect.






                share|improve this answer





















                • 1





                  @Benjamin I think @Nathan's solution is very straightforward and idiomatic for Promises. While your reflect improves code reuse, it also establishes another level of abstraction. Since Nathan's answer has so far only received a fraction of upvotes compared to yours, I wonder whether this is an indication of an issue with his solution, which I haven't recognized yet.

                  – user6445533
                  Jul 9 '16 at 10:54








                • 2





                  @LUH3417 this solution is conceptually less sound since it treats errors as values and does not separate errors from non-errors. For example if one of the promises resolves legitimately to a value that can be thrown (which is entirely possible) this breaks quite badly.

                  – Benjamin Gruenbaum
                  Aug 2 '16 at 14:25






                • 2





                  @BenjaminGruenbaum So for example, new Promise((res, rej) => res(new Error('Legitimate error')) would not be distinguishable from new Promise(((res, rej) => rej(new Error('Illegitimate error'))? Or further, you wouldn't be able to filter by x.status? I'll add this point to my answer so the difference is more clear

                  – Nathan Hagen
                  Aug 2 '16 at 15:53






                • 2





                  The reason this is a poor idea is because it ties the Promise implementation to a specific use case of only ever being used in a specific Promise.all() variant, it also then becomes incumbent on the Promise consumer to know that a specific promise won't reject but will swallow it's errors. In fact the reflect() method could be made less 'abstract' and more explicit by calling it PromiseEvery(promises).then(...).The complexity of the answer above compared to Benjamin's should say much about this solution.

                  – Neil
                  Sep 28 '16 at 21:51


















                56














                Benjamin's answer offers a great abstraction for solving this issue, but I was hoping for a less abstracted solution. The explicit way to to resolve this issue is to simply call .catch on the internal promises, and return the error from their callback.



                let a = new Promise((res, rej) => res('Resolved!')),
                b = new Promise((res, rej) => rej('Rejected!')),
                c = a.catch(e => { console.log('"a" failed.'); return e; }),
                d = b.catch(e => { console.log('"b" failed.'); return e; });

                Promise.all([c, d])
                .then(result => console.log('Then', result)) // Then ["Resolved!", "Rejected!"]
                .catch(err => console.log('Catch', err));

                Promise.all([a.catch(e => e), b.catch(e => e)])
                .then(result => console.log('Then', result)) // Then ["Resolved!", "Rejected!"]
                .catch(err => console.log('Catch', err));




                Taking this one step further, you could write a generic catch handler that looks like this:



                const catchHandler = error => ({ payload: error, resolved: false });


                then you can do



                > Promise.all([a, b].map(promise => promise.catch(catchHandler))
                .then(results => console.log(results))
                .catch(() => console.log('Promise.all failed'))
                < [ 'Resolved!', { payload: Promise, resolved: false } ]


                The problem with this is that the caught values will have a different interface than the non-caught values, so to clean this up you might do something like:



                const successHandler = result => ({ payload: result, resolved: true });


                So now you can do this:



                > Promise.all([a, b].map(result => result.then(successHandler).catch(catchHandler))
                .then(results => console.log(results.filter(result => result.resolved))
                .catch(() => console.log('Promise.all failed'))
                < [ 'Resolved!' ]


                Then to keep it DRY, you get to Benjamin's answer:



                const reflect = promise => promise
                .then(successHandler)
                .catch(catchHander)


                where it now looks like



                > Promise.all([a, b].map(result => result.then(successHandler).catch(catchHandler))
                .then(results => console.log(results.filter(result => result.resolved))
                .catch(() => console.log('Promise.all failed'))
                < [ 'Resolved!' ]




                The benefits of the second solution are that its abstracted and DRY. The downside is you have more code, and you have to remember to reflect all your promises to make things consistent.



                I would characterize my solution as explicit and KISS, but indeed less robust. The interface doesn't guarantee that you know exactly whether the promise succeeded or failed.



                For example you might have this:



                const a = Promise.resolve(new Error('Not beaking, just bad'));
                const b = Promise.reject(new Error('This actually didnt work'));


                This won't get caught by a.catch, so



                > Promise.all([a, b].map(promise => promise.catch(e => e))
                .then(results => console.log(results))
                < [ Error, Error ]


                There's no way to tell which one was fatal and which was wasn't. If that's important then you're going to want to enforce and interface that tracks whether it was successful or not (which reflect does).



                If you just want to handle errors gracefully, then you can just treat errors as undefined values:



                > Promise.all([a.catch(() => undefined), b.catch(() => undefined)])
                .then((results) => console.log('Known values: ', results.filter(x => typeof x !== 'undefined')))
                < [ 'Resolved!' ]


                In my case, I don't need to know the error or how it failed--I just care whether I have the value or not. I'll let the function that generates the promise worry about logging the specific error.



                const apiMethod = () => fetch()
                .catch(error => {
                console.log(error.message);
                throw error;
                });


                That way, the rest of the application can ignore its error if it wants, and treat it as an undefined value if it wants.



                I want my high level functions to fail safely and not worry about the details on why its dependencies failed, and I also prefer KISS to DRY when I have to make that tradeoff--which is ultimately why I opted to not use reflect.






                share|improve this answer





















                • 1





                  @Benjamin I think @Nathan's solution is very straightforward and idiomatic for Promises. While your reflect improves code reuse, it also establishes another level of abstraction. Since Nathan's answer has so far only received a fraction of upvotes compared to yours, I wonder whether this is an indication of an issue with his solution, which I haven't recognized yet.

                  – user6445533
                  Jul 9 '16 at 10:54








                • 2





                  @LUH3417 this solution is conceptually less sound since it treats errors as values and does not separate errors from non-errors. For example if one of the promises resolves legitimately to a value that can be thrown (which is entirely possible) this breaks quite badly.

                  – Benjamin Gruenbaum
                  Aug 2 '16 at 14:25






                • 2





                  @BenjaminGruenbaum So for example, new Promise((res, rej) => res(new Error('Legitimate error')) would not be distinguishable from new Promise(((res, rej) => rej(new Error('Illegitimate error'))? Or further, you wouldn't be able to filter by x.status? I'll add this point to my answer so the difference is more clear

                  – Nathan Hagen
                  Aug 2 '16 at 15:53






                • 2





                  The reason this is a poor idea is because it ties the Promise implementation to a specific use case of only ever being used in a specific Promise.all() variant, it also then becomes incumbent on the Promise consumer to know that a specific promise won't reject but will swallow it's errors. In fact the reflect() method could be made less 'abstract' and more explicit by calling it PromiseEvery(promises).then(...).The complexity of the answer above compared to Benjamin's should say much about this solution.

                  – Neil
                  Sep 28 '16 at 21:51
















                56












                56








                56







                Benjamin's answer offers a great abstraction for solving this issue, but I was hoping for a less abstracted solution. The explicit way to to resolve this issue is to simply call .catch on the internal promises, and return the error from their callback.



                let a = new Promise((res, rej) => res('Resolved!')),
                b = new Promise((res, rej) => rej('Rejected!')),
                c = a.catch(e => { console.log('"a" failed.'); return e; }),
                d = b.catch(e => { console.log('"b" failed.'); return e; });

                Promise.all([c, d])
                .then(result => console.log('Then', result)) // Then ["Resolved!", "Rejected!"]
                .catch(err => console.log('Catch', err));

                Promise.all([a.catch(e => e), b.catch(e => e)])
                .then(result => console.log('Then', result)) // Then ["Resolved!", "Rejected!"]
                .catch(err => console.log('Catch', err));




                Taking this one step further, you could write a generic catch handler that looks like this:



                const catchHandler = error => ({ payload: error, resolved: false });


                then you can do



                > Promise.all([a, b].map(promise => promise.catch(catchHandler))
                .then(results => console.log(results))
                .catch(() => console.log('Promise.all failed'))
                < [ 'Resolved!', { payload: Promise, resolved: false } ]


                The problem with this is that the caught values will have a different interface than the non-caught values, so to clean this up you might do something like:



                const successHandler = result => ({ payload: result, resolved: true });


                So now you can do this:



                > Promise.all([a, b].map(result => result.then(successHandler).catch(catchHandler))
                .then(results => console.log(results.filter(result => result.resolved))
                .catch(() => console.log('Promise.all failed'))
                < [ 'Resolved!' ]


                Then to keep it DRY, you get to Benjamin's answer:



                const reflect = promise => promise
                .then(successHandler)
                .catch(catchHander)


                where it now looks like



                > Promise.all([a, b].map(result => result.then(successHandler).catch(catchHandler))
                .then(results => console.log(results.filter(result => result.resolved))
                .catch(() => console.log('Promise.all failed'))
                < [ 'Resolved!' ]




                The benefits of the second solution are that its abstracted and DRY. The downside is you have more code, and you have to remember to reflect all your promises to make things consistent.



                I would characterize my solution as explicit and KISS, but indeed less robust. The interface doesn't guarantee that you know exactly whether the promise succeeded or failed.



                For example you might have this:



                const a = Promise.resolve(new Error('Not beaking, just bad'));
                const b = Promise.reject(new Error('This actually didnt work'));


                This won't get caught by a.catch, so



                > Promise.all([a, b].map(promise => promise.catch(e => e))
                .then(results => console.log(results))
                < [ Error, Error ]


                There's no way to tell which one was fatal and which was wasn't. If that's important then you're going to want to enforce and interface that tracks whether it was successful or not (which reflect does).



                If you just want to handle errors gracefully, then you can just treat errors as undefined values:



                > Promise.all([a.catch(() => undefined), b.catch(() => undefined)])
                .then((results) => console.log('Known values: ', results.filter(x => typeof x !== 'undefined')))
                < [ 'Resolved!' ]


                In my case, I don't need to know the error or how it failed--I just care whether I have the value or not. I'll let the function that generates the promise worry about logging the specific error.



                const apiMethod = () => fetch()
                .catch(error => {
                console.log(error.message);
                throw error;
                });


                That way, the rest of the application can ignore its error if it wants, and treat it as an undefined value if it wants.



                I want my high level functions to fail safely and not worry about the details on why its dependencies failed, and I also prefer KISS to DRY when I have to make that tradeoff--which is ultimately why I opted to not use reflect.






                share|improve this answer















                Benjamin's answer offers a great abstraction for solving this issue, but I was hoping for a less abstracted solution. The explicit way to to resolve this issue is to simply call .catch on the internal promises, and return the error from their callback.



                let a = new Promise((res, rej) => res('Resolved!')),
                b = new Promise((res, rej) => rej('Rejected!')),
                c = a.catch(e => { console.log('"a" failed.'); return e; }),
                d = b.catch(e => { console.log('"b" failed.'); return e; });

                Promise.all([c, d])
                .then(result => console.log('Then', result)) // Then ["Resolved!", "Rejected!"]
                .catch(err => console.log('Catch', err));

                Promise.all([a.catch(e => e), b.catch(e => e)])
                .then(result => console.log('Then', result)) // Then ["Resolved!", "Rejected!"]
                .catch(err => console.log('Catch', err));




                Taking this one step further, you could write a generic catch handler that looks like this:



                const catchHandler = error => ({ payload: error, resolved: false });


                then you can do



                > Promise.all([a, b].map(promise => promise.catch(catchHandler))
                .then(results => console.log(results))
                .catch(() => console.log('Promise.all failed'))
                < [ 'Resolved!', { payload: Promise, resolved: false } ]


                The problem with this is that the caught values will have a different interface than the non-caught values, so to clean this up you might do something like:



                const successHandler = result => ({ payload: result, resolved: true });


                So now you can do this:



                > Promise.all([a, b].map(result => result.then(successHandler).catch(catchHandler))
                .then(results => console.log(results.filter(result => result.resolved))
                .catch(() => console.log('Promise.all failed'))
                < [ 'Resolved!' ]


                Then to keep it DRY, you get to Benjamin's answer:



                const reflect = promise => promise
                .then(successHandler)
                .catch(catchHander)


                where it now looks like



                > Promise.all([a, b].map(result => result.then(successHandler).catch(catchHandler))
                .then(results => console.log(results.filter(result => result.resolved))
                .catch(() => console.log('Promise.all failed'))
                < [ 'Resolved!' ]




                The benefits of the second solution are that its abstracted and DRY. The downside is you have more code, and you have to remember to reflect all your promises to make things consistent.



                I would characterize my solution as explicit and KISS, but indeed less robust. The interface doesn't guarantee that you know exactly whether the promise succeeded or failed.



                For example you might have this:



                const a = Promise.resolve(new Error('Not beaking, just bad'));
                const b = Promise.reject(new Error('This actually didnt work'));


                This won't get caught by a.catch, so



                > Promise.all([a, b].map(promise => promise.catch(e => e))
                .then(results => console.log(results))
                < [ Error, Error ]


                There's no way to tell which one was fatal and which was wasn't. If that's important then you're going to want to enforce and interface that tracks whether it was successful or not (which reflect does).



                If you just want to handle errors gracefully, then you can just treat errors as undefined values:



                > Promise.all([a.catch(() => undefined), b.catch(() => undefined)])
                .then((results) => console.log('Known values: ', results.filter(x => typeof x !== 'undefined')))
                < [ 'Resolved!' ]


                In my case, I don't need to know the error or how it failed--I just care whether I have the value or not. I'll let the function that generates the promise worry about logging the specific error.



                const apiMethod = () => fetch()
                .catch(error => {
                console.log(error.message);
                throw error;
                });


                That way, the rest of the application can ignore its error if it wants, and treat it as an undefined value if it wants.



                I want my high level functions to fail safely and not worry about the details on why its dependencies failed, and I also prefer KISS to DRY when I have to make that tradeoff--which is ultimately why I opted to not use reflect.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Feb 12 at 4:22









                Shmidt

                11k1674121




                11k1674121










                answered Jul 20 '15 at 19:39









                Nathan HagenNathan Hagen

                6,18232031




                6,18232031








                • 1





                  @Benjamin I think @Nathan's solution is very straightforward and idiomatic for Promises. While your reflect improves code reuse, it also establishes another level of abstraction. Since Nathan's answer has so far only received a fraction of upvotes compared to yours, I wonder whether this is an indication of an issue with his solution, which I haven't recognized yet.

                  – user6445533
                  Jul 9 '16 at 10:54








                • 2





                  @LUH3417 this solution is conceptually less sound since it treats errors as values and does not separate errors from non-errors. For example if one of the promises resolves legitimately to a value that can be thrown (which is entirely possible) this breaks quite badly.

                  – Benjamin Gruenbaum
                  Aug 2 '16 at 14:25






                • 2





                  @BenjaminGruenbaum So for example, new Promise((res, rej) => res(new Error('Legitimate error')) would not be distinguishable from new Promise(((res, rej) => rej(new Error('Illegitimate error'))? Or further, you wouldn't be able to filter by x.status? I'll add this point to my answer so the difference is more clear

                  – Nathan Hagen
                  Aug 2 '16 at 15:53






                • 2





                  The reason this is a poor idea is because it ties the Promise implementation to a specific use case of only ever being used in a specific Promise.all() variant, it also then becomes incumbent on the Promise consumer to know that a specific promise won't reject but will swallow it's errors. In fact the reflect() method could be made less 'abstract' and more explicit by calling it PromiseEvery(promises).then(...).The complexity of the answer above compared to Benjamin's should say much about this solution.

                  – Neil
                  Sep 28 '16 at 21:51
















                • 1





                  @Benjamin I think @Nathan's solution is very straightforward and idiomatic for Promises. While your reflect improves code reuse, it also establishes another level of abstraction. Since Nathan's answer has so far only received a fraction of upvotes compared to yours, I wonder whether this is an indication of an issue with his solution, which I haven't recognized yet.

                  – user6445533
                  Jul 9 '16 at 10:54








                • 2





                  @LUH3417 this solution is conceptually less sound since it treats errors as values and does not separate errors from non-errors. For example if one of the promises resolves legitimately to a value that can be thrown (which is entirely possible) this breaks quite badly.

                  – Benjamin Gruenbaum
                  Aug 2 '16 at 14:25






                • 2





                  @BenjaminGruenbaum So for example, new Promise((res, rej) => res(new Error('Legitimate error')) would not be distinguishable from new Promise(((res, rej) => rej(new Error('Illegitimate error'))? Or further, you wouldn't be able to filter by x.status? I'll add this point to my answer so the difference is more clear

                  – Nathan Hagen
                  Aug 2 '16 at 15:53






                • 2





                  The reason this is a poor idea is because it ties the Promise implementation to a specific use case of only ever being used in a specific Promise.all() variant, it also then becomes incumbent on the Promise consumer to know that a specific promise won't reject but will swallow it's errors. In fact the reflect() method could be made less 'abstract' and more explicit by calling it PromiseEvery(promises).then(...).The complexity of the answer above compared to Benjamin's should say much about this solution.

                  – Neil
                  Sep 28 '16 at 21:51










                1




                1





                @Benjamin I think @Nathan's solution is very straightforward and idiomatic for Promises. While your reflect improves code reuse, it also establishes another level of abstraction. Since Nathan's answer has so far only received a fraction of upvotes compared to yours, I wonder whether this is an indication of an issue with his solution, which I haven't recognized yet.

                – user6445533
                Jul 9 '16 at 10:54







                @Benjamin I think @Nathan's solution is very straightforward and idiomatic for Promises. While your reflect improves code reuse, it also establishes another level of abstraction. Since Nathan's answer has so far only received a fraction of upvotes compared to yours, I wonder whether this is an indication of an issue with his solution, which I haven't recognized yet.

                – user6445533
                Jul 9 '16 at 10:54






                2




                2





                @LUH3417 this solution is conceptually less sound since it treats errors as values and does not separate errors from non-errors. For example if one of the promises resolves legitimately to a value that can be thrown (which is entirely possible) this breaks quite badly.

                – Benjamin Gruenbaum
                Aug 2 '16 at 14:25





                @LUH3417 this solution is conceptually less sound since it treats errors as values and does not separate errors from non-errors. For example if one of the promises resolves legitimately to a value that can be thrown (which is entirely possible) this breaks quite badly.

                – Benjamin Gruenbaum
                Aug 2 '16 at 14:25




                2




                2





                @BenjaminGruenbaum So for example, new Promise((res, rej) => res(new Error('Legitimate error')) would not be distinguishable from new Promise(((res, rej) => rej(new Error('Illegitimate error'))? Or further, you wouldn't be able to filter by x.status? I'll add this point to my answer so the difference is more clear

                – Nathan Hagen
                Aug 2 '16 at 15:53





                @BenjaminGruenbaum So for example, new Promise((res, rej) => res(new Error('Legitimate error')) would not be distinguishable from new Promise(((res, rej) => rej(new Error('Illegitimate error'))? Or further, you wouldn't be able to filter by x.status? I'll add this point to my answer so the difference is more clear

                – Nathan Hagen
                Aug 2 '16 at 15:53




                2




                2





                The reason this is a poor idea is because it ties the Promise implementation to a specific use case of only ever being used in a specific Promise.all() variant, it also then becomes incumbent on the Promise consumer to know that a specific promise won't reject but will swallow it's errors. In fact the reflect() method could be made less 'abstract' and more explicit by calling it PromiseEvery(promises).then(...).The complexity of the answer above compared to Benjamin's should say much about this solution.

                – Neil
                Sep 28 '16 at 21:51







                The reason this is a poor idea is because it ties the Promise implementation to a specific use case of only ever being used in a specific Promise.all() variant, it also then becomes incumbent on the Promise consumer to know that a specific promise won't reject but will swallow it's errors. In fact the reflect() method could be made less 'abstract' and more explicit by calling it PromiseEvery(promises).then(...).The complexity of the answer above compared to Benjamin's should say much about this solution.

                – Neil
                Sep 28 '16 at 21:51













                9














                I really like Benjamin's answer, and how he basically turns all promises into always-resolving-but-sometimes-with-error-as-a-result ones. :)

                Here's my attempt at your request just in case you were looking for alternatives. This method simply treats errors as valid results, and is coded similar to Promise.all otherwise:



                Promise.settle = function(promises) {
                var results = ;
                var done = promises.length;

                return new Promise(function(resolve) {
                function tryResolve(i, v) {
                results[i] = v;
                done = done - 1;
                if (done == 0)
                resolve(results);
                }

                for (var i=0; i<promises.length; i++)
                promises[i].then(tryResolve.bind(null, i), tryResolve.bind(null, i));
                if (done == 0)
                resolve(results);
                });
                }





                share|improve this answer


























                • This is typically called settle. We have that too in bluebird, I like reflect better but this is a viable solution for when you have this for an array.

                  – Benjamin Gruenbaum
                  Jul 15 '15 at 8:31






                • 2





                  OK, settle will be a better name indeed. :)

                  – Kuba Wyrostek
                  Jul 15 '15 at 8:34











                • This looks a lot like the explicit promise construction antipattern. It should be noted that you never should write such a function yourself, but use the one your library supplies (OK, native ES6 is a bit meager).

                  – Bergi
                  Jul 16 '15 at 19:25













                • Could you please use the Promise constructor properly (and avoid that var resolve thingy)?

                  – Bergi
                  Jul 16 '15 at 19:26











                • Bergi, feel free to alter the answer however you consider necessary.

                  – Kuba Wyrostek
                  Jul 16 '15 at 19:33
















                9














                I really like Benjamin's answer, and how he basically turns all promises into always-resolving-but-sometimes-with-error-as-a-result ones. :)

                Here's my attempt at your request just in case you were looking for alternatives. This method simply treats errors as valid results, and is coded similar to Promise.all otherwise:



                Promise.settle = function(promises) {
                var results = ;
                var done = promises.length;

                return new Promise(function(resolve) {
                function tryResolve(i, v) {
                results[i] = v;
                done = done - 1;
                if (done == 0)
                resolve(results);
                }

                for (var i=0; i<promises.length; i++)
                promises[i].then(tryResolve.bind(null, i), tryResolve.bind(null, i));
                if (done == 0)
                resolve(results);
                });
                }





                share|improve this answer


























                • This is typically called settle. We have that too in bluebird, I like reflect better but this is a viable solution for when you have this for an array.

                  – Benjamin Gruenbaum
                  Jul 15 '15 at 8:31






                • 2





                  OK, settle will be a better name indeed. :)

                  – Kuba Wyrostek
                  Jul 15 '15 at 8:34











                • This looks a lot like the explicit promise construction antipattern. It should be noted that you never should write such a function yourself, but use the one your library supplies (OK, native ES6 is a bit meager).

                  – Bergi
                  Jul 16 '15 at 19:25













                • Could you please use the Promise constructor properly (and avoid that var resolve thingy)?

                  – Bergi
                  Jul 16 '15 at 19:26











                • Bergi, feel free to alter the answer however you consider necessary.

                  – Kuba Wyrostek
                  Jul 16 '15 at 19:33














                9












                9








                9







                I really like Benjamin's answer, and how he basically turns all promises into always-resolving-but-sometimes-with-error-as-a-result ones. :)

                Here's my attempt at your request just in case you were looking for alternatives. This method simply treats errors as valid results, and is coded similar to Promise.all otherwise:



                Promise.settle = function(promises) {
                var results = ;
                var done = promises.length;

                return new Promise(function(resolve) {
                function tryResolve(i, v) {
                results[i] = v;
                done = done - 1;
                if (done == 0)
                resolve(results);
                }

                for (var i=0; i<promises.length; i++)
                promises[i].then(tryResolve.bind(null, i), tryResolve.bind(null, i));
                if (done == 0)
                resolve(results);
                });
                }





                share|improve this answer















                I really like Benjamin's answer, and how he basically turns all promises into always-resolving-but-sometimes-with-error-as-a-result ones. :)

                Here's my attempt at your request just in case you were looking for alternatives. This method simply treats errors as valid results, and is coded similar to Promise.all otherwise:



                Promise.settle = function(promises) {
                var results = ;
                var done = promises.length;

                return new Promise(function(resolve) {
                function tryResolve(i, v) {
                results[i] = v;
                done = done - 1;
                if (done == 0)
                resolve(results);
                }

                for (var i=0; i<promises.length; i++)
                promises[i].then(tryResolve.bind(null, i), tryResolve.bind(null, i));
                if (done == 0)
                resolve(results);
                });
                }






                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Jul 17 '15 at 13:07









                Bergi

                382k64589920




                382k64589920










                answered Jul 15 '15 at 8:23









                Kuba WyrostekKuba Wyrostek

                5,2401537




                5,2401537













                • This is typically called settle. We have that too in bluebird, I like reflect better but this is a viable solution for when you have this for an array.

                  – Benjamin Gruenbaum
                  Jul 15 '15 at 8:31






                • 2





                  OK, settle will be a better name indeed. :)

                  – Kuba Wyrostek
                  Jul 15 '15 at 8:34











                • This looks a lot like the explicit promise construction antipattern. It should be noted that you never should write such a function yourself, but use the one your library supplies (OK, native ES6 is a bit meager).

                  – Bergi
                  Jul 16 '15 at 19:25













                • Could you please use the Promise constructor properly (and avoid that var resolve thingy)?

                  – Bergi
                  Jul 16 '15 at 19:26











                • Bergi, feel free to alter the answer however you consider necessary.

                  – Kuba Wyrostek
                  Jul 16 '15 at 19:33



















                • This is typically called settle. We have that too in bluebird, I like reflect better but this is a viable solution for when you have this for an array.

                  – Benjamin Gruenbaum
                  Jul 15 '15 at 8:31






                • 2





                  OK, settle will be a better name indeed. :)

                  – Kuba Wyrostek
                  Jul 15 '15 at 8:34











                • This looks a lot like the explicit promise construction antipattern. It should be noted that you never should write such a function yourself, but use the one your library supplies (OK, native ES6 is a bit meager).

                  – Bergi
                  Jul 16 '15 at 19:25













                • Could you please use the Promise constructor properly (and avoid that var resolve thingy)?

                  – Bergi
                  Jul 16 '15 at 19:26











                • Bergi, feel free to alter the answer however you consider necessary.

                  – Kuba Wyrostek
                  Jul 16 '15 at 19:33

















                This is typically called settle. We have that too in bluebird, I like reflect better but this is a viable solution for when you have this for an array.

                – Benjamin Gruenbaum
                Jul 15 '15 at 8:31





                This is typically called settle. We have that too in bluebird, I like reflect better but this is a viable solution for when you have this for an array.

                – Benjamin Gruenbaum
                Jul 15 '15 at 8:31




                2




                2





                OK, settle will be a better name indeed. :)

                – Kuba Wyrostek
                Jul 15 '15 at 8:34





                OK, settle will be a better name indeed. :)

                – Kuba Wyrostek
                Jul 15 '15 at 8:34













                This looks a lot like the explicit promise construction antipattern. It should be noted that you never should write such a function yourself, but use the one your library supplies (OK, native ES6 is a bit meager).

                – Bergi
                Jul 16 '15 at 19:25







                This looks a lot like the explicit promise construction antipattern. It should be noted that you never should write such a function yourself, but use the one your library supplies (OK, native ES6 is a bit meager).

                – Bergi
                Jul 16 '15 at 19:25















                Could you please use the Promise constructor properly (and avoid that var resolve thingy)?

                – Bergi
                Jul 16 '15 at 19:26





                Could you please use the Promise constructor properly (and avoid that var resolve thingy)?

                – Bergi
                Jul 16 '15 at 19:26













                Bergi, feel free to alter the answer however you consider necessary.

                – Kuba Wyrostek
                Jul 16 '15 at 19:33





                Bergi, feel free to alter the answer however you consider necessary.

                – Kuba Wyrostek
                Jul 16 '15 at 19:33











                4














                var err;
                Promise.all([
                promiseOne().catch(function(error) { err = error;}),
                promiseTwo().catch(function(error) { err = error;})
                ]).then(function() {
                if (err) {
                throw err;
                }
                });


                The Promise.all will swallow any rejected promise and store the error in a variable, so it will return when all of the promises have resolved. Then you can re-throw the error out, or do whatever. In this way, I guess you would get out the last rejection instead of the first one.






                share|improve this answer



















                • 1





                  Seems like this could aggregate errs by making it an array and using err.push(error), so all errors could be bubbled up.

                  – ps2goat
                  Apr 6 '18 at 15:03
















                4














                var err;
                Promise.all([
                promiseOne().catch(function(error) { err = error;}),
                promiseTwo().catch(function(error) { err = error;})
                ]).then(function() {
                if (err) {
                throw err;
                }
                });


                The Promise.all will swallow any rejected promise and store the error in a variable, so it will return when all of the promises have resolved. Then you can re-throw the error out, or do whatever. In this way, I guess you would get out the last rejection instead of the first one.






                share|improve this answer



















                • 1





                  Seems like this could aggregate errs by making it an array and using err.push(error), so all errors could be bubbled up.

                  – ps2goat
                  Apr 6 '18 at 15:03














                4












                4








                4







                var err;
                Promise.all([
                promiseOne().catch(function(error) { err = error;}),
                promiseTwo().catch(function(error) { err = error;})
                ]).then(function() {
                if (err) {
                throw err;
                }
                });


                The Promise.all will swallow any rejected promise and store the error in a variable, so it will return when all of the promises have resolved. Then you can re-throw the error out, or do whatever. In this way, I guess you would get out the last rejection instead of the first one.






                share|improve this answer













                var err;
                Promise.all([
                promiseOne().catch(function(error) { err = error;}),
                promiseTwo().catch(function(error) { err = error;})
                ]).then(function() {
                if (err) {
                throw err;
                }
                });


                The Promise.all will swallow any rejected promise and store the error in a variable, so it will return when all of the promises have resolved. Then you can re-throw the error out, or do whatever. In this way, I guess you would get out the last rejection instead of the first one.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Jan 26 '16 at 20:47









                martin770martin770

                1,083511




                1,083511








                • 1





                  Seems like this could aggregate errs by making it an array and using err.push(error), so all errors could be bubbled up.

                  – ps2goat
                  Apr 6 '18 at 15:03














                • 1





                  Seems like this could aggregate errs by making it an array and using err.push(error), so all errors could be bubbled up.

                  – ps2goat
                  Apr 6 '18 at 15:03








                1




                1





                Seems like this could aggregate errs by making it an array and using err.push(error), so all errors could be bubbled up.

                – ps2goat
                Apr 6 '18 at 15:03





                Seems like this could aggregate errs by making it an array and using err.push(error), so all errors could be bubbled up.

                – ps2goat
                Apr 6 '18 at 15:03











                4














                I had the same problem and have solved it in the following way:



                const fetch = (url) => {
                return node-fetch(url)
                .then(result => result.json())
                .catch((e) => {
                return new Promise((resolve) => setTimeout(() => resolve(fetch(url)), timeout));
                });
                };

                tasks = [fetch(url1), fetch(url2) ....];

                Promise.all(tasks).then(......)


                In that case Promise.all will wait for every Promise will come into resolved or rejected state.



                And having this solution we are "stopping catch execution" in a non-blocking way. In fact, we're not stopping anything, we just returning back the Promise in a pending state which returns another Promise when it's resolved after the timeout.






                share|improve this answer


























                • But that invokes all promises at will when you run Promise.all. I'm looking for a way to listen for when all promises have been invoked, but not invoke them myself. Thanks.

                  – SudoPlz
                  Jan 3 '18 at 12:25













                • @SudoPlz the method all() does that, it waits for the fulfilment of all Promises or rejection at least one of it.

                  – user1016265
                  Jan 3 '18 at 20:46













                • that's true, but it doesn't just wait, it actually invokes/starts/fires up the process. If you wished to fire up the promises someplace else that wouldn't be possible, becase .all fires everything up.

                  – SudoPlz
                  Jan 3 '18 at 21:10













                • @SudoPlz hope this will change your opinion jsfiddle.net/d1z1vey5

                  – user1016265
                  Jan 4 '18 at 21:35






                • 2





                  I stand corrected. Until now I thought Promises only run when someone invokes them (a.k.a a then or an .all call) but they run when created.

                  – SudoPlz
                  Jan 5 '18 at 0:23


















                4














                I had the same problem and have solved it in the following way:



                const fetch = (url) => {
                return node-fetch(url)
                .then(result => result.json())
                .catch((e) => {
                return new Promise((resolve) => setTimeout(() => resolve(fetch(url)), timeout));
                });
                };

                tasks = [fetch(url1), fetch(url2) ....];

                Promise.all(tasks).then(......)


                In that case Promise.all will wait for every Promise will come into resolved or rejected state.



                And having this solution we are "stopping catch execution" in a non-blocking way. In fact, we're not stopping anything, we just returning back the Promise in a pending state which returns another Promise when it's resolved after the timeout.






                share|improve this answer


























                • But that invokes all promises at will when you run Promise.all. I'm looking for a way to listen for when all promises have been invoked, but not invoke them myself. Thanks.

                  – SudoPlz
                  Jan 3 '18 at 12:25













                • @SudoPlz the method all() does that, it waits for the fulfilment of all Promises or rejection at least one of it.

                  – user1016265
                  Jan 3 '18 at 20:46













                • that's true, but it doesn't just wait, it actually invokes/starts/fires up the process. If you wished to fire up the promises someplace else that wouldn't be possible, becase .all fires everything up.

                  – SudoPlz
                  Jan 3 '18 at 21:10













                • @SudoPlz hope this will change your opinion jsfiddle.net/d1z1vey5

                  – user1016265
                  Jan 4 '18 at 21:35






                • 2





                  I stand corrected. Until now I thought Promises only run when someone invokes them (a.k.a a then or an .all call) but they run when created.

                  – SudoPlz
                  Jan 5 '18 at 0:23
















                4












                4








                4







                I had the same problem and have solved it in the following way:



                const fetch = (url) => {
                return node-fetch(url)
                .then(result => result.json())
                .catch((e) => {
                return new Promise((resolve) => setTimeout(() => resolve(fetch(url)), timeout));
                });
                };

                tasks = [fetch(url1), fetch(url2) ....];

                Promise.all(tasks).then(......)


                In that case Promise.all will wait for every Promise will come into resolved or rejected state.



                And having this solution we are "stopping catch execution" in a non-blocking way. In fact, we're not stopping anything, we just returning back the Promise in a pending state which returns another Promise when it's resolved after the timeout.






                share|improve this answer















                I had the same problem and have solved it in the following way:



                const fetch = (url) => {
                return node-fetch(url)
                .then(result => result.json())
                .catch((e) => {
                return new Promise((resolve) => setTimeout(() => resolve(fetch(url)), timeout));
                });
                };

                tasks = [fetch(url1), fetch(url2) ....];

                Promise.all(tasks).then(......)


                In that case Promise.all will wait for every Promise will come into resolved or rejected state.



                And having this solution we are "stopping catch execution" in a non-blocking way. In fact, we're not stopping anything, we just returning back the Promise in a pending state which returns another Promise when it's resolved after the timeout.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Nov 22 '17 at 15:17

























                answered Jul 3 '17 at 9:05









                user1016265user1016265

                1,09231742




                1,09231742













                • But that invokes all promises at will when you run Promise.all. I'm looking for a way to listen for when all promises have been invoked, but not invoke them myself. Thanks.

                  – SudoPlz
                  Jan 3 '18 at 12:25













                • @SudoPlz the method all() does that, it waits for the fulfilment of all Promises or rejection at least one of it.

                  – user1016265
                  Jan 3 '18 at 20:46













                • that's true, but it doesn't just wait, it actually invokes/starts/fires up the process. If you wished to fire up the promises someplace else that wouldn't be possible, becase .all fires everything up.

                  – SudoPlz
                  Jan 3 '18 at 21:10













                • @SudoPlz hope this will change your opinion jsfiddle.net/d1z1vey5

                  – user1016265
                  Jan 4 '18 at 21:35






                • 2





                  I stand corrected. Until now I thought Promises only run when someone invokes them (a.k.a a then or an .all call) but they run when created.

                  – SudoPlz
                  Jan 5 '18 at 0:23





















                • But that invokes all promises at will when you run Promise.all. I'm looking for a way to listen for when all promises have been invoked, but not invoke them myself. Thanks.

                  – SudoPlz
                  Jan 3 '18 at 12:25













                • @SudoPlz the method all() does that, it waits for the fulfilment of all Promises or rejection at least one of it.

                  – user1016265
                  Jan 3 '18 at 20:46













                • that's true, but it doesn't just wait, it actually invokes/starts/fires up the process. If you wished to fire up the promises someplace else that wouldn't be possible, becase .all fires everything up.

                  – SudoPlz
                  Jan 3 '18 at 21:10













                • @SudoPlz hope this will change your opinion jsfiddle.net/d1z1vey5

                  – user1016265
                  Jan 4 '18 at 21:35






                • 2





                  I stand corrected. Until now I thought Promises only run when someone invokes them (a.k.a a then or an .all call) but they run when created.

                  – SudoPlz
                  Jan 5 '18 at 0:23



















                But that invokes all promises at will when you run Promise.all. I'm looking for a way to listen for when all promises have been invoked, but not invoke them myself. Thanks.

                – SudoPlz
                Jan 3 '18 at 12:25







                But that invokes all promises at will when you run Promise.all. I'm looking for a way to listen for when all promises have been invoked, but not invoke them myself. Thanks.

                – SudoPlz
                Jan 3 '18 at 12:25















                @SudoPlz the method all() does that, it waits for the fulfilment of all Promises or rejection at least one of it.

                – user1016265
                Jan 3 '18 at 20:46







                @SudoPlz the method all() does that, it waits for the fulfilment of all Promises or rejection at least one of it.

                – user1016265
                Jan 3 '18 at 20:46















                that's true, but it doesn't just wait, it actually invokes/starts/fires up the process. If you wished to fire up the promises someplace else that wouldn't be possible, becase .all fires everything up.

                – SudoPlz
                Jan 3 '18 at 21:10







                that's true, but it doesn't just wait, it actually invokes/starts/fires up the process. If you wished to fire up the promises someplace else that wouldn't be possible, becase .all fires everything up.

                – SudoPlz
                Jan 3 '18 at 21:10















                @SudoPlz hope this will change your opinion jsfiddle.net/d1z1vey5

                – user1016265
                Jan 4 '18 at 21:35





                @SudoPlz hope this will change your opinion jsfiddle.net/d1z1vey5

                – user1016265
                Jan 4 '18 at 21:35




                2




                2





                I stand corrected. Until now I thought Promises only run when someone invokes them (a.k.a a then or an .all call) but they run when created.

                – SudoPlz
                Jan 5 '18 at 0:23







                I stand corrected. Until now I thought Promises only run when someone invokes them (a.k.a a then or an .all call) but they run when created.

                – SudoPlz
                Jan 5 '18 at 0:23













                2














                This should be consistent with how Q does it:



                if(!Promise.allSettled) {
                Promise.allSettled = function (promises) {
                return Promise.all(promises.map(p => Promise.resolve(p).then(v => ({
                state: 'fulfilled',
                value: v,
                }), r => ({
                state: 'rejected',
                reason: r,
                }))));
                };
                }





                share|improve this answer




























                  2














                  This should be consistent with how Q does it:



                  if(!Promise.allSettled) {
                  Promise.allSettled = function (promises) {
                  return Promise.all(promises.map(p => Promise.resolve(p).then(v => ({
                  state: 'fulfilled',
                  value: v,
                  }), r => ({
                  state: 'rejected',
                  reason: r,
                  }))));
                  };
                  }





                  share|improve this answer


























                    2












                    2








                    2







                    This should be consistent with how Q does it:



                    if(!Promise.allSettled) {
                    Promise.allSettled = function (promises) {
                    return Promise.all(promises.map(p => Promise.resolve(p).then(v => ({
                    state: 'fulfilled',
                    value: v,
                    }), r => ({
                    state: 'rejected',
                    reason: r,
                    }))));
                    };
                    }





                    share|improve this answer













                    This should be consistent with how Q does it:



                    if(!Promise.allSettled) {
                    Promise.allSettled = function (promises) {
                    return Promise.all(promises.map(p => Promise.resolve(p).then(v => ({
                    state: 'fulfilled',
                    value: v,
                    }), r => ({
                    state: 'rejected',
                    reason: r,
                    }))));
                    };
                    }






                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Oct 22 '16 at 21:44









                    mpenmpen

                    127k178659960




                    127k178659960























                        2














                        Benjamin Gruenbaum answer is of course great,. But I can also see were Nathan Hagen point of view with the level of abstraction seem vague. Having short object properties like e & v don't help either, but of course that could be changed.



                        In Javascript there is standard Error object, called Error,. Ideally you always throw an instance / descendant of this. The advantage is that you can do instanceof Error, and you know something is an error.



                        So using this idea, here is my take on the problem.



                        Basically catch the error, if the error is not of type Error, wrap the error inside an Error object. The resulting array will have either resolved values, or Error objects you can check on.



                        The instanceof inside the catch, is in case you use some external library that maybe did reject("error"), instead of reject(new Error("error")).



                        Of course you could have promises were you resolve an error, but in that case it would most likely make sense to treat as an error anyway, like the last example shows.



                        Another advantage of doing it this, array destructing is kept simple.



                        const [value1, value2] = PromiseAllCatch(promises);
                        if (!(value1 instanceof Error)) console.log(value1);


                        Instead of



                        const [{v: value1, e: error1}, {v: value2, e: error2}] = Promise.all(reflect..
                        if (!error1) { console.log(value1); }


                        You could argue that the !error1 check is simpler than an instanceof, but your also having to destruct both v & e.






                        function PromiseAllCatch(promises) {
                        return Promise.all(promises.map(async m => {
                        try {
                        return await m;
                        } catch(e) {
                        if (e instanceof Error) return e;
                        return new Error(e);
                        }
                        }));
                        }


                        async function test() {
                        const ret = await PromiseAllCatch([
                        (async () => "this is fine")(),
                        (async () => {throw new Error("oops")})(),
                        (async () => "this is ok")(),
                        (async () => {throw "Still an error";})(),
                        (async () => new Error("resolved Error"))(),
                        ]);
                        console.log(ret);
                        console.log(ret.map(r =>
                        r instanceof Error ? "error" : "ok"
                        ).join(" : "));
                        }

                        test();








                        share|improve this answer






























                          2














                          Benjamin Gruenbaum answer is of course great,. But I can also see were Nathan Hagen point of view with the level of abstraction seem vague. Having short object properties like e & v don't help either, but of course that could be changed.



                          In Javascript there is standard Error object, called Error,. Ideally you always throw an instance / descendant of this. The advantage is that you can do instanceof Error, and you know something is an error.



                          So using this idea, here is my take on the problem.



                          Basically catch the error, if the error is not of type Error, wrap the error inside an Error object. The resulting array will have either resolved values, or Error objects you can check on.



                          The instanceof inside the catch, is in case you use some external library that maybe did reject("error"), instead of reject(new Error("error")).



                          Of course you could have promises were you resolve an error, but in that case it would most likely make sense to treat as an error anyway, like the last example shows.



                          Another advantage of doing it this, array destructing is kept simple.



                          const [value1, value2] = PromiseAllCatch(promises);
                          if (!(value1 instanceof Error)) console.log(value1);


                          Instead of



                          const [{v: value1, e: error1}, {v: value2, e: error2}] = Promise.all(reflect..
                          if (!error1) { console.log(value1); }


                          You could argue that the !error1 check is simpler than an instanceof, but your also having to destruct both v & e.






                          function PromiseAllCatch(promises) {
                          return Promise.all(promises.map(async m => {
                          try {
                          return await m;
                          } catch(e) {
                          if (e instanceof Error) return e;
                          return new Error(e);
                          }
                          }));
                          }


                          async function test() {
                          const ret = await PromiseAllCatch([
                          (async () => "this is fine")(),
                          (async () => {throw new Error("oops")})(),
                          (async () => "this is ok")(),
                          (async () => {throw "Still an error";})(),
                          (async () => new Error("resolved Error"))(),
                          ]);
                          console.log(ret);
                          console.log(ret.map(r =>
                          r instanceof Error ? "error" : "ok"
                          ).join(" : "));
                          }

                          test();








                          share|improve this answer




























                            2












                            2








                            2







                            Benjamin Gruenbaum answer is of course great,. But I can also see were Nathan Hagen point of view with the level of abstraction seem vague. Having short object properties like e & v don't help either, but of course that could be changed.



                            In Javascript there is standard Error object, called Error,. Ideally you always throw an instance / descendant of this. The advantage is that you can do instanceof Error, and you know something is an error.



                            So using this idea, here is my take on the problem.



                            Basically catch the error, if the error is not of type Error, wrap the error inside an Error object. The resulting array will have either resolved values, or Error objects you can check on.



                            The instanceof inside the catch, is in case you use some external library that maybe did reject("error"), instead of reject(new Error("error")).



                            Of course you could have promises were you resolve an error, but in that case it would most likely make sense to treat as an error anyway, like the last example shows.



                            Another advantage of doing it this, array destructing is kept simple.



                            const [value1, value2] = PromiseAllCatch(promises);
                            if (!(value1 instanceof Error)) console.log(value1);


                            Instead of



                            const [{v: value1, e: error1}, {v: value2, e: error2}] = Promise.all(reflect..
                            if (!error1) { console.log(value1); }


                            You could argue that the !error1 check is simpler than an instanceof, but your also having to destruct both v & e.






                            function PromiseAllCatch(promises) {
                            return Promise.all(promises.map(async m => {
                            try {
                            return await m;
                            } catch(e) {
                            if (e instanceof Error) return e;
                            return new Error(e);
                            }
                            }));
                            }


                            async function test() {
                            const ret = await PromiseAllCatch([
                            (async () => "this is fine")(),
                            (async () => {throw new Error("oops")})(),
                            (async () => "this is ok")(),
                            (async () => {throw "Still an error";})(),
                            (async () => new Error("resolved Error"))(),
                            ]);
                            console.log(ret);
                            console.log(ret.map(r =>
                            r instanceof Error ? "error" : "ok"
                            ).join(" : "));
                            }

                            test();








                            share|improve this answer















                            Benjamin Gruenbaum answer is of course great,. But I can also see were Nathan Hagen point of view with the level of abstraction seem vague. Having short object properties like e & v don't help either, but of course that could be changed.



                            In Javascript there is standard Error object, called Error,. Ideally you always throw an instance / descendant of this. The advantage is that you can do instanceof Error, and you know something is an error.



                            So using this idea, here is my take on the problem.



                            Basically catch the error, if the error is not of type Error, wrap the error inside an Error object. The resulting array will have either resolved values, or Error objects you can check on.



                            The instanceof inside the catch, is in case you use some external library that maybe did reject("error"), instead of reject(new Error("error")).



                            Of course you could have promises were you resolve an error, but in that case it would most likely make sense to treat as an error anyway, like the last example shows.



                            Another advantage of doing it this, array destructing is kept simple.



                            const [value1, value2] = PromiseAllCatch(promises);
                            if (!(value1 instanceof Error)) console.log(value1);


                            Instead of



                            const [{v: value1, e: error1}, {v: value2, e: error2}] = Promise.all(reflect..
                            if (!error1) { console.log(value1); }


                            You could argue that the !error1 check is simpler than an instanceof, but your also having to destruct both v & e.






                            function PromiseAllCatch(promises) {
                            return Promise.all(promises.map(async m => {
                            try {
                            return await m;
                            } catch(e) {
                            if (e instanceof Error) return e;
                            return new Error(e);
                            }
                            }));
                            }


                            async function test() {
                            const ret = await PromiseAllCatch([
                            (async () => "this is fine")(),
                            (async () => {throw new Error("oops")})(),
                            (async () => "this is ok")(),
                            (async () => {throw "Still an error";})(),
                            (async () => new Error("resolved Error"))(),
                            ]);
                            console.log(ret);
                            console.log(ret.map(r =>
                            r instanceof Error ? "error" : "ok"
                            ).join(" : "));
                            }

                            test();








                            function PromiseAllCatch(promises) {
                            return Promise.all(promises.map(async m => {
                            try {
                            return await m;
                            } catch(e) {
                            if (e instanceof Error) return e;
                            return new Error(e);
                            }
                            }));
                            }


                            async function test() {
                            const ret = await PromiseAllCatch([
                            (async () => "this is fine")(),
                            (async () => {throw new Error("oops")})(),
                            (async () => "this is ok")(),
                            (async () => {throw "Still an error";})(),
                            (async () => new Error("resolved Error"))(),
                            ]);
                            console.log(ret);
                            console.log(ret.map(r =>
                            r instanceof Error ? "error" : "ok"
                            ).join(" : "));
                            }

                            test();





                            function PromiseAllCatch(promises) {
                            return Promise.all(promises.map(async m => {
                            try {
                            return await m;
                            } catch(e) {
                            if (e instanceof Error) return e;
                            return new Error(e);
                            }
                            }));
                            }


                            async function test() {
                            const ret = await PromiseAllCatch([
                            (async () => "this is fine")(),
                            (async () => {throw new Error("oops")})(),
                            (async () => "this is ok")(),
                            (async () => {throw "Still an error";})(),
                            (async () => new Error("resolved Error"))(),
                            ]);
                            console.log(ret);
                            console.log(ret.map(r =>
                            r instanceof Error ? "error" : "ok"
                            ).join(" : "));
                            }

                            test();






                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Mar 8 at 13:43

























                            answered Mar 8 at 13:15









                            KeithKeith

                            9,2881821




                            9,2881821























                                0














                                Here's my custom settledPromiseAll()



                                const settledPromiseAll = function(promisesArray) {
                                var savedError;

                                const saveFirstError = function(error) {
                                if (!savedError) savedError = error;
                                };
                                const handleErrors = function(value) {
                                return Promise.resolve(value).catch(saveFirstError);
                                };
                                const allSettled = Promise.all(promisesArray.map(handleErrors));

                                return allSettled.then(function(resolvedPromises) {
                                if (savedError) throw savedError;
                                return resolvedPromises;
                                });
                                };


                                Compared to Promise.all




                                • If all promises are resolved, it performs exactly as the standard one.


                                • If one of more promises are rejected, it returns the first one rejected much the same as the standard one but unlike it waits for all promises to resolve/reject.



                                For the brave we could change Promise.all():



                                (function() {
                                var stdAll = Promise.all;

                                Promise.all = function(values, wait) {
                                if(!wait)
                                return stdAll.call(Promise, values);

                                return settledPromiseAll(values);
                                }
                                })();


                                CAREFUL. In general we never change built-ins, as it might break other unrelated JS libraries or clash with future changes to JS standards.



                                My settledPromiseall is backward compatible with Promise.all and extends its functionality.



                                People who are developing standards -- why not include this to a new Promise standard?






                                share|improve this answer






























                                  0














                                  Here's my custom settledPromiseAll()



                                  const settledPromiseAll = function(promisesArray) {
                                  var savedError;

                                  const saveFirstError = function(error) {
                                  if (!savedError) savedError = error;
                                  };
                                  const handleErrors = function(value) {
                                  return Promise.resolve(value).catch(saveFirstError);
                                  };
                                  const allSettled = Promise.all(promisesArray.map(handleErrors));

                                  return allSettled.then(function(resolvedPromises) {
                                  if (savedError) throw savedError;
                                  return resolvedPromises;
                                  });
                                  };


                                  Compared to Promise.all




                                  • If all promises are resolved, it performs exactly as the standard one.


                                  • If one of more promises are rejected, it returns the first one rejected much the same as the standard one but unlike it waits for all promises to resolve/reject.



                                  For the brave we could change Promise.all():



                                  (function() {
                                  var stdAll = Promise.all;

                                  Promise.all = function(values, wait) {
                                  if(!wait)
                                  return stdAll.call(Promise, values);

                                  return settledPromiseAll(values);
                                  }
                                  })();


                                  CAREFUL. In general we never change built-ins, as it might break other unrelated JS libraries or clash with future changes to JS standards.



                                  My settledPromiseall is backward compatible with Promise.all and extends its functionality.



                                  People who are developing standards -- why not include this to a new Promise standard?






                                  share|improve this answer




























                                    0












                                    0








                                    0







                                    Here's my custom settledPromiseAll()



                                    const settledPromiseAll = function(promisesArray) {
                                    var savedError;

                                    const saveFirstError = function(error) {
                                    if (!savedError) savedError = error;
                                    };
                                    const handleErrors = function(value) {
                                    return Promise.resolve(value).catch(saveFirstError);
                                    };
                                    const allSettled = Promise.all(promisesArray.map(handleErrors));

                                    return allSettled.then(function(resolvedPromises) {
                                    if (savedError) throw savedError;
                                    return resolvedPromises;
                                    });
                                    };


                                    Compared to Promise.all




                                    • If all promises are resolved, it performs exactly as the standard one.


                                    • If one of more promises are rejected, it returns the first one rejected much the same as the standard one but unlike it waits for all promises to resolve/reject.



                                    For the brave we could change Promise.all():



                                    (function() {
                                    var stdAll = Promise.all;

                                    Promise.all = function(values, wait) {
                                    if(!wait)
                                    return stdAll.call(Promise, values);

                                    return settledPromiseAll(values);
                                    }
                                    })();


                                    CAREFUL. In general we never change built-ins, as it might break other unrelated JS libraries or clash with future changes to JS standards.



                                    My settledPromiseall is backward compatible with Promise.all and extends its functionality.



                                    People who are developing standards -- why not include this to a new Promise standard?






                                    share|improve this answer















                                    Here's my custom settledPromiseAll()



                                    const settledPromiseAll = function(promisesArray) {
                                    var savedError;

                                    const saveFirstError = function(error) {
                                    if (!savedError) savedError = error;
                                    };
                                    const handleErrors = function(value) {
                                    return Promise.resolve(value).catch(saveFirstError);
                                    };
                                    const allSettled = Promise.all(promisesArray.map(handleErrors));

                                    return allSettled.then(function(resolvedPromises) {
                                    if (savedError) throw savedError;
                                    return resolvedPromises;
                                    });
                                    };


                                    Compared to Promise.all




                                    • If all promises are resolved, it performs exactly as the standard one.


                                    • If one of more promises are rejected, it returns the first one rejected much the same as the standard one but unlike it waits for all promises to resolve/reject.



                                    For the brave we could change Promise.all():



                                    (function() {
                                    var stdAll = Promise.all;

                                    Promise.all = function(values, wait) {
                                    if(!wait)
                                    return stdAll.call(Promise, values);

                                    return settledPromiseAll(values);
                                    }
                                    })();


                                    CAREFUL. In general we never change built-ins, as it might break other unrelated JS libraries or clash with future changes to JS standards.



                                    My settledPromiseall is backward compatible with Promise.all and extends its functionality.



                                    People who are developing standards -- why not include this to a new Promise standard?







                                    share|improve this answer














                                    share|improve this answer



                                    share|improve this answer








                                    edited Oct 24 '18 at 16:52









                                    Simon B.

                                    1,292823




                                    1,292823










                                    answered Jul 25 '18 at 23:26









                                    EdwardEdward

                                    5914




                                    5914























                                        0














                                        I think the following offers a slightly different approach... compare fn_fast_fail() with fn_slow_fail()... though the latter doesn't fail as such... you can check if one or both of a and b is an instance of Error and throw that Error if you want it to reach the catch block (e.g. if (b instanceof Error) { throw b; }) . See the jsfiddle.



                                        var p1 = new Promise((resolve, reject) => { 
                                        setTimeout(() => resolve('p1_delayed_resolvement'), 2000);
                                        });

                                        var p2 = new Promise((resolve, reject) => {
                                        reject(new Error('p2_immediate_rejection'));
                                        });

                                        var fn_fast_fail = async function () {
                                        try {
                                        var [a, b] = await Promise.all([p1, p2]);
                                        console.log(a); // "p1_delayed_resolvement"
                                        console.log(b); // "Error: p2_immediate_rejection"
                                        } catch (err) {
                                        console.log('ERROR:', err);
                                        }
                                        }

                                        var fn_slow_fail = async function () {
                                        try {
                                        var [a, b] = await Promise.all([
                                        p1.catch(error => { return error }),
                                        p2.catch(error => { return error })
                                        ]);
                                        console.log(a); // "p1_delayed_resolvement"
                                        console.log(b); // "Error: p2_immediate_rejection"
                                        } catch (err) {
                                        // we don't reach here unless you throw the error from the `try` block
                                        console.log('ERROR:', err);
                                        }
                                        }

                                        fn_fast_fail(); // fails immediately
                                        fn_slow_fail(); // waits for delayed promise to resolve





                                        share|improve this answer






























                                          0














                                          I think the following offers a slightly different approach... compare fn_fast_fail() with fn_slow_fail()... though the latter doesn't fail as such... you can check if one or both of a and b is an instance of Error and throw that Error if you want it to reach the catch block (e.g. if (b instanceof Error) { throw b; }) . See the jsfiddle.



                                          var p1 = new Promise((resolve, reject) => { 
                                          setTimeout(() => resolve('p1_delayed_resolvement'), 2000);
                                          });

                                          var p2 = new Promise((resolve, reject) => {
                                          reject(new Error('p2_immediate_rejection'));
                                          });

                                          var fn_fast_fail = async function () {
                                          try {
                                          var [a, b] = await Promise.all([p1, p2]);
                                          console.log(a); // "p1_delayed_resolvement"
                                          console.log(b); // "Error: p2_immediate_rejection"
                                          } catch (err) {
                                          console.log('ERROR:', err);
                                          }
                                          }

                                          var fn_slow_fail = async function () {
                                          try {
                                          var [a, b] = await Promise.all([
                                          p1.catch(error => { return error }),
                                          p2.catch(error => { return error })
                                          ]);
                                          console.log(a); // "p1_delayed_resolvement"
                                          console.log(b); // "Error: p2_immediate_rejection"
                                          } catch (err) {
                                          // we don't reach here unless you throw the error from the `try` block
                                          console.log('ERROR:', err);
                                          }
                                          }

                                          fn_fast_fail(); // fails immediately
                                          fn_slow_fail(); // waits for delayed promise to resolve





                                          share|improve this answer




























                                            0












                                            0








                                            0







                                            I think the following offers a slightly different approach... compare fn_fast_fail() with fn_slow_fail()... though the latter doesn't fail as such... you can check if one or both of a and b is an instance of Error and throw that Error if you want it to reach the catch block (e.g. if (b instanceof Error) { throw b; }) . See the jsfiddle.



                                            var p1 = new Promise((resolve, reject) => { 
                                            setTimeout(() => resolve('p1_delayed_resolvement'), 2000);
                                            });

                                            var p2 = new Promise((resolve, reject) => {
                                            reject(new Error('p2_immediate_rejection'));
                                            });

                                            var fn_fast_fail = async function () {
                                            try {
                                            var [a, b] = await Promise.all([p1, p2]);
                                            console.log(a); // "p1_delayed_resolvement"
                                            console.log(b); // "Error: p2_immediate_rejection"
                                            } catch (err) {
                                            console.log('ERROR:', err);
                                            }
                                            }

                                            var fn_slow_fail = async function () {
                                            try {
                                            var [a, b] = await Promise.all([
                                            p1.catch(error => { return error }),
                                            p2.catch(error => { return error })
                                            ]);
                                            console.log(a); // "p1_delayed_resolvement"
                                            console.log(b); // "Error: p2_immediate_rejection"
                                            } catch (err) {
                                            // we don't reach here unless you throw the error from the `try` block
                                            console.log('ERROR:', err);
                                            }
                                            }

                                            fn_fast_fail(); // fails immediately
                                            fn_slow_fail(); // waits for delayed promise to resolve





                                            share|improve this answer















                                            I think the following offers a slightly different approach... compare fn_fast_fail() with fn_slow_fail()... though the latter doesn't fail as such... you can check if one or both of a and b is an instance of Error and throw that Error if you want it to reach the catch block (e.g. if (b instanceof Error) { throw b; }) . See the jsfiddle.



                                            var p1 = new Promise((resolve, reject) => { 
                                            setTimeout(() => resolve('p1_delayed_resolvement'), 2000);
                                            });

                                            var p2 = new Promise((resolve, reject) => {
                                            reject(new Error('p2_immediate_rejection'));
                                            });

                                            var fn_fast_fail = async function () {
                                            try {
                                            var [a, b] = await Promise.all([p1, p2]);
                                            console.log(a); // "p1_delayed_resolvement"
                                            console.log(b); // "Error: p2_immediate_rejection"
                                            } catch (err) {
                                            console.log('ERROR:', err);
                                            }
                                            }

                                            var fn_slow_fail = async function () {
                                            try {
                                            var [a, b] = await Promise.all([
                                            p1.catch(error => { return error }),
                                            p2.catch(error => { return error })
                                            ]);
                                            console.log(a); // "p1_delayed_resolvement"
                                            console.log(b); // "Error: p2_immediate_rejection"
                                            } catch (err) {
                                            // we don't reach here unless you throw the error from the `try` block
                                            console.log('ERROR:', err);
                                            }
                                            }

                                            fn_fast_fail(); // fails immediately
                                            fn_slow_fail(); // waits for delayed promise to resolve






                                            share|improve this answer














                                            share|improve this answer



                                            share|improve this answer








                                            edited Nov 16 '18 at 20:52

























                                            answered Nov 16 '18 at 20:15









                                            drmrbrewerdrmrbrewer

                                            2,21573290




                                            2,21573290























                                                -1














                                                I would do:



                                                var err = [fetch('index.html').then((success) => { return Promise.resolve(success); }).catch((e) => { return Promise.resolve(e); }),
                                                fetch('http://does-not-exist').then((success) => { return Promise.resolve(success); }).catch((e) => { return Promise.resolve(e); })];

                                                Promise.all(err)
                                                .then(function (res) { console.log('success', res) })
                                                .catch(function (err) { console.log('error', err) }) //never executed





                                                share|improve this answer




























                                                  -1














                                                  I would do:



                                                  var err = [fetch('index.html').then((success) => { return Promise.resolve(success); }).catch((e) => { return Promise.resolve(e); }),
                                                  fetch('http://does-not-exist').then((success) => { return Promise.resolve(success); }).catch((e) => { return Promise.resolve(e); })];

                                                  Promise.all(err)
                                                  .then(function (res) { console.log('success', res) })
                                                  .catch(function (err) { console.log('error', err) }) //never executed





                                                  share|improve this answer


























                                                    -1












                                                    -1








                                                    -1







                                                    I would do:



                                                    var err = [fetch('index.html').then((success) => { return Promise.resolve(success); }).catch((e) => { return Promise.resolve(e); }),
                                                    fetch('http://does-not-exist').then((success) => { return Promise.resolve(success); }).catch((e) => { return Promise.resolve(e); })];

                                                    Promise.all(err)
                                                    .then(function (res) { console.log('success', res) })
                                                    .catch(function (err) { console.log('error', err) }) //never executed





                                                    share|improve this answer













                                                    I would do:



                                                    var err = [fetch('index.html').then((success) => { return Promise.resolve(success); }).catch((e) => { return Promise.resolve(e); }),
                                                    fetch('http://does-not-exist').then((success) => { return Promise.resolve(success); }).catch((e) => { return Promise.resolve(e); })];

                                                    Promise.all(err)
                                                    .then(function (res) { console.log('success', res) })
                                                    .catch(function (err) { console.log('error', err) }) //never executed






                                                    share|improve this answer












                                                    share|improve this answer



                                                    share|improve this answer










                                                    answered Jun 8 '16 at 20:59









                                                    FRochaFRocha

                                                    1095




                                                    1095























                                                        -1














                                                        You can execute your logic sequentially via synchronous executor nsynjs. It will pause on each promise, wait for resolution/rejection, and either assign resolve's result to data property, or throw an exception (for handling that you will need try/catch block). Here is an example:






                                                        function synchronousCode() {
                                                        function myFetch(url) {
                                                        try {
                                                        return window.fetch(url).data;
                                                        }
                                                        catch (e) {
                                                        return {status: 'failed:'+e};
                                                        };
                                                        };
                                                        var arr=[
                                                        myFetch("https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"),
                                                        myFetch("https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/NONEXISTANT.js"),
                                                        myFetch("https://ajax.NONEXISTANT123.com/ajax/libs/jquery/2.0.0/NONEXISTANT.js")
                                                        ];

                                                        console.log('array is ready:',arr[0].status,arr[1].status,arr[2].status);
                                                        };

                                                        nsynjs.run(synchronousCode,{},function(){
                                                        console.log('done');
                                                        });

                                                        <script src="https://rawgit.com/amaksr/nsynjs/master/nsynjs.js"></script>








                                                        share|improve this answer






























                                                          -1














                                                          You can execute your logic sequentially via synchronous executor nsynjs. It will pause on each promise, wait for resolution/rejection, and either assign resolve's result to data property, or throw an exception (for handling that you will need try/catch block). Here is an example:






                                                          function synchronousCode() {
                                                          function myFetch(url) {
                                                          try {
                                                          return window.fetch(url).data;
                                                          }
                                                          catch (e) {
                                                          return {status: 'failed:'+e};
                                                          };
                                                          };
                                                          var arr=[
                                                          myFetch("https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"),
                                                          myFetch("https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/NONEXISTANT.js"),
                                                          myFetch("https://ajax.NONEXISTANT123.com/ajax/libs/jquery/2.0.0/NONEXISTANT.js")
                                                          ];

                                                          console.log('array is ready:',arr[0].status,arr[1].status,arr[2].status);
                                                          };

                                                          nsynjs.run(synchronousCode,{},function(){
                                                          console.log('done');
                                                          });

                                                          <script src="https://rawgit.com/amaksr/nsynjs/master/nsynjs.js"></script>








                                                          share|improve this answer




























                                                            -1












                                                            -1








                                                            -1







                                                            You can execute your logic sequentially via synchronous executor nsynjs. It will pause on each promise, wait for resolution/rejection, and either assign resolve's result to data property, or throw an exception (for handling that you will need try/catch block). Here is an example:






                                                            function synchronousCode() {
                                                            function myFetch(url) {
                                                            try {
                                                            return window.fetch(url).data;
                                                            }
                                                            catch (e) {
                                                            return {status: 'failed:'+e};
                                                            };
                                                            };
                                                            var arr=[
                                                            myFetch("https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"),
                                                            myFetch("https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/NONEXISTANT.js"),
                                                            myFetch("https://ajax.NONEXISTANT123.com/ajax/libs/jquery/2.0.0/NONEXISTANT.js")
                                                            ];

                                                            console.log('array is ready:',arr[0].status,arr[1].status,arr[2].status);
                                                            };

                                                            nsynjs.run(synchronousCode,{},function(){
                                                            console.log('done');
                                                            });

                                                            <script src="https://rawgit.com/amaksr/nsynjs/master/nsynjs.js"></script>








                                                            share|improve this answer















                                                            You can execute your logic sequentially via synchronous executor nsynjs. It will pause on each promise, wait for resolution/rejection, and either assign resolve's result to data property, or throw an exception (for handling that you will need try/catch block). Here is an example:






                                                            function synchronousCode() {
                                                            function myFetch(url) {
                                                            try {
                                                            return window.fetch(url).data;
                                                            }
                                                            catch (e) {
                                                            return {status: 'failed:'+e};
                                                            };
                                                            };
                                                            var arr=[
                                                            myFetch("https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"),
                                                            myFetch("https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/NONEXISTANT.js"),
                                                            myFetch("https://ajax.NONEXISTANT123.com/ajax/libs/jquery/2.0.0/NONEXISTANT.js")
                                                            ];

                                                            console.log('array is ready:',arr[0].status,arr[1].status,arr[2].status);
                                                            };

                                                            nsynjs.run(synchronousCode,{},function(){
                                                            console.log('done');
                                                            });

                                                            <script src="https://rawgit.com/amaksr/nsynjs/master/nsynjs.js"></script>








                                                            function synchronousCode() {
                                                            function myFetch(url) {
                                                            try {
                                                            return window.fetch(url).data;
                                                            }
                                                            catch (e) {
                                                            return {status: 'failed:'+e};
                                                            };
                                                            };
                                                            var arr=[
                                                            myFetch("https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"),
                                                            myFetch("https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/NONEXISTANT.js"),
                                                            myFetch("https://ajax.NONEXISTANT123.com/ajax/libs/jquery/2.0.0/NONEXISTANT.js")
                                                            ];

                                                            console.log('array is ready:',arr[0].status,arr[1].status,arr[2].status);
                                                            };

                                                            nsynjs.run(synchronousCode,{},function(){
                                                            console.log('done');
                                                            });

                                                            <script src="https://rawgit.com/amaksr/nsynjs/master/nsynjs.js"></script>





                                                            function synchronousCode() {
                                                            function myFetch(url) {
                                                            try {
                                                            return window.fetch(url).data;
                                                            }
                                                            catch (e) {
                                                            return {status: 'failed:'+e};
                                                            };
                                                            };
                                                            var arr=[
                                                            myFetch("https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"),
                                                            myFetch("https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/NONEXISTANT.js"),
                                                            myFetch("https://ajax.NONEXISTANT123.com/ajax/libs/jquery/2.0.0/NONEXISTANT.js")
                                                            ];

                                                            console.log('array is ready:',arr[0].status,arr[1].status,arr[2].status);
                                                            };

                                                            nsynjs.run(synchronousCode,{},function(){
                                                            console.log('done');
                                                            });

                                                            <script src="https://rawgit.com/amaksr/nsynjs/master/nsynjs.js"></script>






                                                            share|improve this answer














                                                            share|improve this answer



                                                            share|improve this answer








                                                            edited Jun 11 '17 at 17:09

























                                                            answered Jun 11 '17 at 17:02









                                                            amaksramaksr

                                                            5,28521016




                                                            5,28521016























                                                                -1














                                                                I've been using following codes since ES5.



                                                                Promise.wait = function(promiseQueue){
                                                                if( !Array.isArray(promiseQueue) ){
                                                                return Promise.reject('Given parameter is not an array!');
                                                                }

                                                                if( promiseQueue.length === 0 ){
                                                                return Promise.resolve();
                                                                }

                                                                return new Promise((resolve, reject) =>{
                                                                let _pQueue=, _rQueue=, _readyCount=false;
                                                                promiseQueue.forEach((_promise, idx) =>{
                                                                // Create a status info object
                                                                _rQueue.push({rejected:false, seq:idx, result:null});
                                                                _pQueue.push(Promise.resolve(_promise));
                                                                });

                                                                _pQueue.forEach((_promise, idx)=>{
                                                                let item = _rQueue[idx];
                                                                _promise.then(
                                                                (result)=>{
                                                                item.resolved = true;
                                                                item.result = result;
                                                                },
                                                                (error)=>{
                                                                item.resolved = false;
                                                                item.result = error;
                                                                }
                                                                ).then(()=>{
                                                                _readyCount++;

                                                                if ( _rQueue.length === _readyCount ) {
                                                                let result = true;
                                                                _rQueue.forEach((item)=>{result=result&&item.resolved;});
                                                                (result?resolve:reject)(_rQueue);
                                                                }
                                                                });
                                                                });
                                                                });
                                                                };


                                                                The usage signature is just like Promise.all. The major difference is that Promise.wait will wait for all the promises to finish their jobs.






                                                                share|improve this answer




























                                                                  -1














                                                                  I've been using following codes since ES5.



                                                                  Promise.wait = function(promiseQueue){
                                                                  if( !Array.isArray(promiseQueue) ){
                                                                  return Promise.reject('Given parameter is not an array!');
                                                                  }

                                                                  if( promiseQueue.length === 0 ){
                                                                  return Promise.resolve();
                                                                  }

                                                                  return new Promise((resolve, reject) =>{
                                                                  let _pQueue=, _rQueue=, _readyCount=false;
                                                                  promiseQueue.forEach((_promise, idx) =>{
                                                                  // Create a status info object
                                                                  _rQueue.push({rejected:false, seq:idx, result:null});
                                                                  _pQueue.push(Promise.resolve(_promise));
                                                                  });

                                                                  _pQueue.forEach((_promise, idx)=>{
                                                                  let item = _rQueue[idx];
                                                                  _promise.then(
                                                                  (result)=>{
                                                                  item.resolved = true;
                                                                  item.result = result;
                                                                  },
                                                                  (error)=>{
                                                                  item.resolved = false;
                                                                  item.result = error;
                                                                  }
                                                                  ).then(()=>{
                                                                  _readyCount++;

                                                                  if ( _rQueue.length === _readyCount ) {
                                                                  let result = true;
                                                                  _rQueue.forEach((item)=>{result=result&&item.resolved;});
                                                                  (result?resolve:reject)(_rQueue);
                                                                  }
                                                                  });
                                                                  });
                                                                  });
                                                                  };


                                                                  The usage signature is just like Promise.all. The major difference is that Promise.wait will wait for all the promises to finish their jobs.






                                                                  share|improve this answer


























                                                                    -1












                                                                    -1








                                                                    -1







                                                                    I've been using following codes since ES5.



                                                                    Promise.wait = function(promiseQueue){
                                                                    if( !Array.isArray(promiseQueue) ){
                                                                    return Promise.reject('Given parameter is not an array!');
                                                                    }

                                                                    if( promiseQueue.length === 0 ){
                                                                    return Promise.resolve();
                                                                    }

                                                                    return new Promise((resolve, reject) =>{
                                                                    let _pQueue=, _rQueue=, _readyCount=false;
                                                                    promiseQueue.forEach((_promise, idx) =>{
                                                                    // Create a status info object
                                                                    _rQueue.push({rejected:false, seq:idx, result:null});
                                                                    _pQueue.push(Promise.resolve(_promise));
                                                                    });

                                                                    _pQueue.forEach((_promise, idx)=>{
                                                                    let item = _rQueue[idx];
                                                                    _promise.then(
                                                                    (result)=>{
                                                                    item.resolved = true;
                                                                    item.result = result;
                                                                    },
                                                                    (error)=>{
                                                                    item.resolved = false;
                                                                    item.result = error;
                                                                    }
                                                                    ).then(()=>{
                                                                    _readyCount++;

                                                                    if ( _rQueue.length === _readyCount ) {
                                                                    let result = true;
                                                                    _rQueue.forEach((item)=>{result=result&&item.resolved;});
                                                                    (result?resolve:reject)(_rQueue);
                                                                    }
                                                                    });
                                                                    });
                                                                    });
                                                                    };


                                                                    The usage signature is just like Promise.all. The major difference is that Promise.wait will wait for all the promises to finish their jobs.






                                                                    share|improve this answer













                                                                    I've been using following codes since ES5.



                                                                    Promise.wait = function(promiseQueue){
                                                                    if( !Array.isArray(promiseQueue) ){
                                                                    return Promise.reject('Given parameter is not an array!');
                                                                    }

                                                                    if( promiseQueue.length === 0 ){
                                                                    return Promise.resolve();
                                                                    }

                                                                    return new Promise((resolve, reject) =>{
                                                                    let _pQueue=, _rQueue=, _readyCount=false;
                                                                    promiseQueue.forEach((_promise, idx) =>{
                                                                    // Create a status info object
                                                                    _rQueue.push({rejected:false, seq:idx, result:null});
                                                                    _pQueue.push(Promise.resolve(_promise));
                                                                    });

                                                                    _pQueue.forEach((_promise, idx)=>{
                                                                    let item = _rQueue[idx];
                                                                    _promise.then(
                                                                    (result)=>{
                                                                    item.resolved = true;
                                                                    item.result = result;
                                                                    },
                                                                    (error)=>{
                                                                    item.resolved = false;
                                                                    item.result = error;
                                                                    }
                                                                    ).then(()=>{
                                                                    _readyCount++;

                                                                    if ( _rQueue.length === _readyCount ) {
                                                                    let result = true;
                                                                    _rQueue.forEach((item)=>{result=result&&item.resolved;});
                                                                    (result?resolve:reject)(_rQueue);
                                                                    }
                                                                    });
                                                                    });
                                                                    });
                                                                    };


                                                                    The usage signature is just like Promise.all. The major difference is that Promise.wait will wait for all the promises to finish their jobs.







                                                                    share|improve this answer












                                                                    share|improve this answer



                                                                    share|improve this answer










                                                                    answered Sep 13 '18 at 4:12









                                                                    user2273990user2273990

                                                                    1




                                                                    1























                                                                        -1














                                                                        I know that this question has a lot of answers, and I'm sure must (if not all) are correct.
                                                                        However it was very hard for me to understand the logic/flow of these answers.



                                                                        So I looked at the Original Implementation on Promise.all(), and I tried to imitate that logic - with the exception of not stopping the execution if one Promise failed.



                                                                          public promiseExecuteAll(promisesList: Promise<any> = ): Promise<{ data: any, isSuccess: boolean }>
                                                                        {
                                                                        let promise: Promise<{ data: any, isSuccess: boolean }>;

                                                                        if (promisesList.length)
                                                                        {
                                                                        const result: { data: any, isSuccess: boolean } = ;
                                                                        let count: number = 0;

                                                                        promise = new Promise<{ data: any, isSuccess: boolean }>((resolve, reject) =>
                                                                        {
                                                                        promisesList.forEach((currentPromise: Promise<any>, index: number) =>
                                                                        {
                                                                        currentPromise.then(
                                                                        (data) => // Success
                                                                        {
                                                                        result[index] = { data, isSuccess: true };
                                                                        if (promisesList.length <= ++count) { resolve(result); }
                                                                        },
                                                                        (data) => // Error
                                                                        {
                                                                        result[index] = { data, isSuccess: false };
                                                                        if (promisesList.length <= ++count) { resolve(result); }
                                                                        });
                                                                        });
                                                                        });
                                                                        }
                                                                        else
                                                                        {
                                                                        promise = Promise.resolve();
                                                                        }

                                                                        return promise;
                                                                        }


                                                                        Explanation:

                                                                        - Loop over the input promisesList and execute each Promise.

                                                                        - No matter if the Promise resolved or rejected: save the Promise's result in a result array according to the index. Save also the resolve/reject status (isSuccess).

                                                                        - Once all Promises completed, return one Promise with the result of all others.



                                                                        Example of use:



                                                                        const p1 = Promise.resolve("OK");
                                                                        const p2 = Promise.reject(new Error(":-("));
                                                                        const p3 = Promise.resolve(1000);

                                                                        promiseExecuteAll([p1, p2, p3]).then((data) => {
                                                                        data.forEach(value => console.log(`${ value.isSuccess ? 'Resolve' : 'Reject' } >> ${ value.data }`));
                                                                        });

                                                                        /* Output:
                                                                        Resolve >> OK
                                                                        Reject >> :-(
                                                                        Resolve >> 1000
                                                                        */





                                                                        share|improve this answer





















                                                                        • 1





                                                                          Don't try to re-implement Promise.all yourself, there are too many things that will go wrong. Your version doesn't handle empty inputs for example.

                                                                          – Bergi
                                                                          Mar 8 at 14:04
















                                                                        -1














                                                                        I know that this question has a lot of answers, and I'm sure must (if not all) are correct.
                                                                        However it was very hard for me to understand the logic/flow of these answers.



                                                                        So I looked at the Original Implementation on Promise.all(), and I tried to imitate that logic - with the exception of not stopping the execution if one Promise failed.



                                                                          public promiseExecuteAll(promisesList: Promise<any> = ): Promise<{ data: any, isSuccess: boolean }>
                                                                        {
                                                                        let promise: Promise<{ data: any, isSuccess: boolean }>;

                                                                        if (promisesList.length)
                                                                        {
                                                                        const result: { data: any, isSuccess: boolean } = ;
                                                                        let count: number = 0;

                                                                        promise = new Promise<{ data: any, isSuccess: boolean }>((resolve, reject) =>
                                                                        {
                                                                        promisesList.forEach((currentPromise: Promise<any>, index: number) =>
                                                                        {
                                                                        currentPromise.then(
                                                                        (data) => // Success
                                                                        {
                                                                        result[index] = { data, isSuccess: true };
                                                                        if (promisesList.length <= ++count) { resolve(result); }
                                                                        },
                                                                        (data) => // Error
                                                                        {
                                                                        result[index] = { data, isSuccess: false };
                                                                        if (promisesList.length <= ++count) { resolve(result); }
                                                                        });
                                                                        });
                                                                        });
                                                                        }
                                                                        else
                                                                        {
                                                                        promise = Promise.resolve();
                                                                        }

                                                                        return promise;
                                                                        }


                                                                        Explanation:

                                                                        - Loop over the input promisesList and execute each Promise.

                                                                        - No matter if the Promise resolved or rejected: save the Promise's result in a result array according to the index. Save also the resolve/reject status (isSuccess).

                                                                        - Once all Promises completed, return one Promise with the result of all others.



                                                                        Example of use:



                                                                        const p1 = Promise.resolve("OK");
                                                                        const p2 = Promise.reject(new Error(":-("));
                                                                        const p3 = Promise.resolve(1000);

                                                                        promiseExecuteAll([p1, p2, p3]).then((data) => {
                                                                        data.forEach(value => console.log(`${ value.isSuccess ? 'Resolve' : 'Reject' } >> ${ value.data }`));
                                                                        });

                                                                        /* Output:
                                                                        Resolve >> OK
                                                                        Reject >> :-(
                                                                        Resolve >> 1000
                                                                        */





                                                                        share|improve this answer





















                                                                        • 1





                                                                          Don't try to re-implement Promise.all yourself, there are too many things that will go wrong. Your version doesn't handle empty inputs for example.

                                                                          – Bergi
                                                                          Mar 8 at 14:04














                                                                        -1












                                                                        -1








                                                                        -1







                                                                        I know that this question has a lot of answers, and I'm sure must (if not all) are correct.
                                                                        However it was very hard for me to understand the logic/flow of these answers.



                                                                        So I looked at the Original Implementation on Promise.all(), and I tried to imitate that logic - with the exception of not stopping the execution if one Promise failed.



                                                                          public promiseExecuteAll(promisesList: Promise<any> = ): Promise<{ data: any, isSuccess: boolean }>
                                                                        {
                                                                        let promise: Promise<{ data: any, isSuccess: boolean }>;

                                                                        if (promisesList.length)
                                                                        {
                                                                        const result: { data: any, isSuccess: boolean } = ;
                                                                        let count: number = 0;

                                                                        promise = new Promise<{ data: any, isSuccess: boolean }>((resolve, reject) =>
                                                                        {
                                                                        promisesList.forEach((currentPromise: Promise<any>, index: number) =>
                                                                        {
                                                                        currentPromise.then(
                                                                        (data) => // Success
                                                                        {
                                                                        result[index] = { data, isSuccess: true };
                                                                        if (promisesList.length <= ++count) { resolve(result); }
                                                                        },
                                                                        (data) => // Error
                                                                        {
                                                                        result[index] = { data, isSuccess: false };
                                                                        if (promisesList.length <= ++count) { resolve(result); }
                                                                        });
                                                                        });
                                                                        });
                                                                        }
                                                                        else
                                                                        {
                                                                        promise = Promise.resolve();
                                                                        }

                                                                        return promise;
                                                                        }


                                                                        Explanation:

                                                                        - Loop over the input promisesList and execute each Promise.

                                                                        - No matter if the Promise resolved or rejected: save the Promise's result in a result array according to the index. Save also the resolve/reject status (isSuccess).

                                                                        - Once all Promises completed, return one Promise with the result of all others.



                                                                        Example of use:



                                                                        const p1 = Promise.resolve("OK");
                                                                        const p2 = Promise.reject(new Error(":-("));
                                                                        const p3 = Promise.resolve(1000);

                                                                        promiseExecuteAll([p1, p2, p3]).then((data) => {
                                                                        data.forEach(value => console.log(`${ value.isSuccess ? 'Resolve' : 'Reject' } >> ${ value.data }`));
                                                                        });

                                                                        /* Output:
                                                                        Resolve >> OK
                                                                        Reject >> :-(
                                                                        Resolve >> 1000
                                                                        */





                                                                        share|improve this answer















                                                                        I know that this question has a lot of answers, and I'm sure must (if not all) are correct.
                                                                        However it was very hard for me to understand the logic/flow of these answers.



                                                                        So I looked at the Original Implementation on Promise.all(), and I tried to imitate that logic - with the exception of not stopping the execution if one Promise failed.



                                                                          public promiseExecuteAll(promisesList: Promise<any> = ): Promise<{ data: any, isSuccess: boolean }>
                                                                        {
                                                                        let promise: Promise<{ data: any, isSuccess: boolean }>;

                                                                        if (promisesList.length)
                                                                        {
                                                                        const result: { data: any, isSuccess: boolean } = ;
                                                                        let count: number = 0;

                                                                        promise = new Promise<{ data: any, isSuccess: boolean }>((resolve, reject) =>
                                                                        {
                                                                        promisesList.forEach((currentPromise: Promise<any>, index: number) =>
                                                                        {
                                                                        currentPromise.then(
                                                                        (data) => // Success
                                                                        {
                                                                        result[index] = { data, isSuccess: true };
                                                                        if (promisesList.length <= ++count) { resolve(result); }
                                                                        },
                                                                        (data) => // Error
                                                                        {
                                                                        result[index] = { data, isSuccess: false };
                                                                        if (promisesList.length <= ++count) { resolve(result); }
                                                                        });
                                                                        });
                                                                        });
                                                                        }
                                                                        else
                                                                        {
                                                                        promise = Promise.resolve();
                                                                        }

                                                                        return promise;
                                                                        }


                                                                        Explanation:

                                                                        - Loop over the input promisesList and execute each Promise.

                                                                        - No matter if the Promise resolved or rejected: save the Promise's result in a result array according to the index. Save also the resolve/reject status (isSuccess).

                                                                        - Once all Promises completed, return one Promise with the result of all others.



                                                                        Example of use:



                                                                        const p1 = Promise.resolve("OK");
                                                                        const p2 = Promise.reject(new Error(":-("));
                                                                        const p3 = Promise.resolve(1000);

                                                                        promiseExecuteAll([p1, p2, p3]).then((data) => {
                                                                        data.forEach(value => console.log(`${ value.isSuccess ? 'Resolve' : 'Reject' } >> ${ value.data }`));
                                                                        });

                                                                        /* Output:
                                                                        Resolve >> OK
                                                                        Reject >> :-(
                                                                        Resolve >> 1000
                                                                        */






                                                                        share|improve this answer














                                                                        share|improve this answer



                                                                        share|improve this answer








                                                                        edited Mar 13 at 8:54

























                                                                        answered Feb 13 at 12:34









                                                                        Gil EpshtainGil Epshtain

                                                                        2,08442246




                                                                        2,08442246








                                                                        • 1





                                                                          Don't try to re-implement Promise.all yourself, there are too many things that will go wrong. Your version doesn't handle empty inputs for example.

                                                                          – Bergi
                                                                          Mar 8 at 14:04














                                                                        • 1





                                                                          Don't try to re-implement Promise.all yourself, there are too many things that will go wrong. Your version doesn't handle empty inputs for example.

                                                                          – Bergi
                                                                          Mar 8 at 14:04








                                                                        1




                                                                        1





                                                                        Don't try to re-implement Promise.all yourself, there are too many things that will go wrong. Your version doesn't handle empty inputs for example.

                                                                        – Bergi
                                                                        Mar 8 at 14:04





                                                                        Don't try to re-implement Promise.all yourself, there are too many things that will go wrong. Your version doesn't handle empty inputs for example.

                                                                        – Bergi
                                                                        Mar 8 at 14:04











                                                                        -3














                                                                        I don't know which promise library you are using, but most have something like allSettled.



                                                                        Edit: Ok since you want to use plain ES6 without external libraries, there is no such method.



                                                                        In other words: You have to loop over your promises manually and resolve a new combined promise as soon as all promises are settled.






                                                                        share|improve this answer


























                                                                        • I've edited my question to clarify--Since ES6 comes with promises, I'd like to avoid using another library for what I would think is basic functionality. I guess a good place to get the answer from would be to copy the source from one of the promise libraries.

                                                                          – Nathan Hagen
                                                                          Jul 15 '15 at 8:05
















                                                                        -3














                                                                        I don't know which promise library you are using, but most have something like allSettled.



                                                                        Edit: Ok since you want to use plain ES6 without external libraries, there is no such method.



                                                                        In other words: You have to loop over your promises manually and resolve a new combined promise as soon as all promises are settled.






                                                                        share|improve this answer


























                                                                        • I've edited my question to clarify--Since ES6 comes with promises, I'd like to avoid using another library for what I would think is basic functionality. I guess a good place to get the answer from would be to copy the source from one of the promise libraries.

                                                                          – Nathan Hagen
                                                                          Jul 15 '15 at 8:05














                                                                        -3












                                                                        -3








                                                                        -3







                                                                        I don't know which promise library you are using, but most have something like allSettled.



                                                                        Edit: Ok since you want to use plain ES6 without external libraries, there is no such method.



                                                                        In other words: You have to loop over your promises manually and resolve a new combined promise as soon as all promises are settled.






                                                                        share|improve this answer















                                                                        I don't know which promise library you are using, but most have something like allSettled.



                                                                        Edit: Ok since you want to use plain ES6 without external libraries, there is no such method.



                                                                        In other words: You have to loop over your promises manually and resolve a new combined promise as soon as all promises are settled.







                                                                        share|improve this answer














                                                                        share|improve this answer



                                                                        share|improve this answer








                                                                        edited Jul 15 '15 at 8:08

























                                                                        answered Jul 15 '15 at 8:01









                                                                        Sebastian SSebastian S

                                                                        2,33921841




                                                                        2,33921841













                                                                        • I've edited my question to clarify--Since ES6 comes with promises, I'd like to avoid using another library for what I would think is basic functionality. I guess a good place to get the answer from would be to copy the source from one of the promise libraries.

                                                                          – Nathan Hagen
                                                                          Jul 15 '15 at 8:05



















                                                                        • I've edited my question to clarify--Since ES6 comes with promises, I'd like to avoid using another library for what I would think is basic functionality. I guess a good place to get the answer from would be to copy the source from one of the promise libraries.

                                                                          – Nathan Hagen
                                                                          Jul 15 '15 at 8:05

















                                                                        I've edited my question to clarify--Since ES6 comes with promises, I'd like to avoid using another library for what I would think is basic functionality. I guess a good place to get the answer from would be to copy the source from one of the promise libraries.

                                                                        – Nathan Hagen
                                                                        Jul 15 '15 at 8:05





                                                                        I've edited my question to clarify--Since ES6 comes with promises, I'd like to avoid using another library for what I would think is basic functionality. I guess a good place to get the answer from would be to copy the source from one of the promise libraries.

                                                                        – Nathan Hagen
                                                                        Jul 15 '15 at 8:05





                                                                        protected by Josh Crozier Dec 9 '18 at 5:26



                                                                        Thank you for your interest in this question.
                                                                        Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



                                                                        Would you like to answer one of these unanswered questions instead?



                                                                        Popular posts from this blog

                                                                        Xamarin.iOS Cant Deploy on Iphone

                                                                        Glorious Revolution

                                                                        Dulmage-Mendelsohn matrix decomposition in Python