Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Try/Catch with Promise.all

I have recently been reading about async/await and using try and catch to handle promise rejections, and have been applying it to some of my old code.

I have the following:

async function() {
    try {
        await Promise.all([some functions]);
        doIfNoError();
    } catch (error) {
        console.log(error);
    }

The functions I am passing to Promise.all follow the form:

async function() {
    some code
    if (some condition) {
        return true
    } else {
        throw false
    }
 }

I intend that if any of the functions passed into Promise.all reject, the rejection is displayed. If none of the functions reject, then doIfNoError should fire. However, doIfNoError sometimes fires when it shouldn't, and I am given the error "Unhandled Promise Rejection".

like image 995
tom894 Avatar asked Dec 30 '18 20:12

tom894


2 Answers

Actually, try/catch does work well with Promise.all().

Here is a snippet to prove it:

async function p1() {
  return 1;
}
async function boom() {
  throw new Error('boom');
}

// expected output: 'boom', ["value before Promise.all"]
async function asyncCall() {
  let all = ['value before Promise.all'];
  try {
    all = await Promise.all([p1(), boom()]);
  } catch(e) {
    console.log(e.message);
  }
  console.log(JSON.stringify(all));
}

asyncCall();
like image 123
Pleymor Avatar answered Oct 10 '22 05:10

Pleymor


Try using promises to their full potential, which includes a catch block for rejected promises. Note that if doIfNoError also throws an error, it will be caught with catch.

async function() {
    await Promise.all([some promises])
    .then(doIfNoError) // Promise.all resolved
    .catch(console.log) // Promise.all has at least one rejection
}

promiseAll = async (promises) => {
  await Promise.all(promises)
  .then(doIfNoError) // Promise.all resolved
  .catch(console.log) // Promise.all has at least one rejection
}
    
doIfNoError = () => console.log('No errors');

promiseAll([Promise.resolve(), 1, true, () => (false)]);
promiseAll([Promise.resolve(), 1, true, Promise.reject('rejected: because reasons'), Promise.resolve()]);

It's often considered bad practice to mix async/await with Promise chains. Using a try/catch should work just fine.

promiseAll = async (promises) => {
  try {
    await Promise.all(promises);
    doIfNoError(); // Promise.all resolved
  } catch(error) {
    console.log(error); // Promise.all has at least one rejection
  }
}
    
doIfNoError = () => console.log('No errors');

promiseAll([Promise.resolve(), 1, true, () => (false)]);
promiseAll([Promise.resolve(), 1, true, Promise.reject('rejected: because reasons'), Promise.resolve()]);
like image 23
Drew Reese Avatar answered Oct 10 '22 05:10

Drew Reese