1

The code below should actually catch the error thrown by the async function but, it is showing resolved of then block.

const {
  forEach
} = require("lodash");
async function test(num) {
  await (async() =>
    setTimeout(() => {
      if (num == 11) {
        throw 'err';
      }
    }, 1000))();
  return num;
}
test(11).then(() =>
  console.log("Resolved")
).catch(() =>
  console.log("Rejected")
);
Prathamesh More
  • 1,470
  • 2
  • 18
  • 32
Rohit Kumar
  • 65
  • 1
  • 8

3 Answers3

3

Because you are not returning a promise.

async function test(num) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (num === 11) reject("err")
            resolve(num);
        }, 1000)
    });
}

test(11).then(() =>
  console.log("Resolved")
).catch(() =>
  console.log("Rejected")
);
barbarbar338
  • 616
  • 5
  • 15
  • Doesn't async function itself return a promise? Also, if I change reject 'err' to throw 'err' in your code then it still goes unnoticed – Rohit Kumar Feb 28 '21 at 10:16
3

I believe that the more straightforward approach here is to stick with promises.

function test(num) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (num == 11) {
        reject(new Error('Rejected!'));
      } else {
        resolve(num);
      }
    }, 1000);
  });
}

If you're set on async/await, one possible approach could be the following, as suggested in this post.

function timeout(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function test(num) {
  await timeout(1000);

  if (num == 11) {
    throw new Error('Rejected!');
  } else {
    return num;
  }
}
greenBox
  • 552
  • 4
  • 5
1

This is because the setTimeout is synchronous function. Yes, the setTimeout adds some code to execute asynchronously, however the setTimeout itself is executed on the main thread (synchronously).

As result, your

async() =>
    setTimeout(() => {
      if (num == 11) {
        throw 'err';
      }
    }, 1000))()

completes immediately (synchronously), after its completion, your "then" is triggered, and only after one second, an error is thrown

  • It should actually await there till the task is completed and then it should only return. I have used await keyword before that. Is there anything I am missing? – Rohit Kumar Feb 28 '21 at 10:26
  • 1
    setTimeout doesn't return a promise so `await` has no effect on it, other answers have shown how to convert it to a promise api. – Matt Feb 28 '21 at 11:06
  • 1
    Thanks I have understood the concept now. – Rohit Kumar Feb 28 '21 at 12:00