skip to Main Content

Assuming I have a

function(){
  ....
  return Promise.all([p1,p2])
}

And I want to instead return a promise of p1, p2, p3, with p3 starting only after p1 and p2 are done. What would be the best way?

Would the following work:

function(){
  ....
  return Promise.all([p1,p2]).then(
    (p) => {
      return Promise.all(p.push(p3));
    })
}

Anything special to handle rejected promises?

2

Answers


  1. What you had would work conceptually, but not practically because p.push() returns the new length of the array, not the array. So, you could fix it like this:

    function(){
      ....
      return Promise.all([p1,p2]).then((values) => {
          values.push(fn3());  // start operation 3 and add p3 to the array
          return Promise.all(values);
      });
    }
    

    This also assumes that you only start the operation that returns p3 after the first Promise.all() returns.

    I would personally prefer to use await like this, but it gives the same result:

    async function someFunc() {
        ...
        const values = await Promise.all([p1, p2]);
        values.push(fn3());  // start operation 3 and add p3 to the array
        return Promise.all(values);
    }
    

    This works because Promise.all() accepts an array of promises or values or a mix of the two. For values in the array (anything other than a promise), it just immediately adds them to the results array (no need to wait for a promise).


    Or, perhaps a little simpler to read where the code is a bit more self descriptive for what you actually want to do, you could just do this:

    async function someFunc() {
        ...
        const values = await Promise.all([p1, p2]);
        values.push(await fn3());   // start operation 3
        return values;
    }
    

    This last option would be my favorite.

    Login or Signup to reply.
  2. Spread syntax

    If you prefer the format you’ve already got, you could alternatively use the array spread syntax to do this:

    function(){
      ....
      return Promise.all([p1,p2]).then(
        (p) => {
          const p3 = f3(); // start p3
          return Promise.all([...p, p3]);
        })
    }
    

    Error handling

    Take note that the documentation for Promise.all states:

    It rejects when any of the input’s promises rejects, with this first rejection reason.

    So whichever promise rejects first will trigger a reject for Promise.all() and only that rejection is a provided as an argument for catch((err) => { ... }).

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search