1

I want to combine asynchronous functions that i need to await and functions I don't need to await. First the code...

async function doSomeStuff() {
  try {

    const data = await getDataFromDatabase()

    if(data.canDoStuff == "yes") {
       doAsynchronousStuffIDoNotNeedToAwait()
    }

    if(data.canDoSecondStuff == "yes") {
       doSecondAsynchronousStuffIDoNotNeedToAwait()
          .then(result => console.log("Done!");
    }

  } catch(err) {
    console.log(err)
  }
}

Here is my questions. If my doAsynchronousStuffIDoNotNeedToAwait() throws an error, does it trigger the catch function? In second function doSecondAsynchronousStuffIDoNotNeedToAwait() is there a better way of handling the result? Does this code have some downsides or can it be written better way?

I hope that questions are clear and code is simple enough to understand. If not please leave comment and I will edit my question. Thank you :)

Raold
  • 1,383
  • 4
  • 20
  • 33
  • 1
    This is not a duplicate of the question suggested. Not all asynchronous executions are built on promises. Additionally, it is not necessarily obvious to someone coming to this question that "firing and forgetting" is the principle that is being attempted - identifying that would form a useful part of the answer to this question. – J. Stott Nov 20 '18 at 09:23

2 Answers2

1

Well, let's get it a try:

function getDataFromDatabase() {
  return new Promise((resolve) => {
    setTimeout(resolve, 250, {canDoStuff: 'yes', canDoSecondStuff: 'yes'});
  });
}
function doAsynchronousStuffIDoNotNeedToAwait() {
  return new Promise((resolve) => {
    setTimeout(resolve, 250);
  });
}
function doSecondAsynchronousStuffIDoNotNeedToAwait() {
  return new Promise((_, reject) => {
    setTimeout(reject, 250, 'error: doSecondAsynchronousStuffIDoNotNeedToAwait()');
  });
}
async function doSomeStuff() {
  try {

    const data = await getDataFromDatabase()
    if(data.canDoStuff == "yes") {
       doAsynchronousStuffIDoNotNeedToAwait()
    }

    if(data.canDoSecondStuff == "yes") {
       doSecondAsynchronousStuffIDoNotNeedToAwait()
          .then(result => console.log("Done!"));
    }

  } catch(err) {
    console.log(err)
  }
}
doSomeStuff();

As you can see by running the snippet, no the error won't get caught by the try/catch, but you will get a global? error as the promise is not within the "scope" of the try catch, the only errors that get caught by the async await try/catch is when a normal exception is thrown or an awaited promised gets rejected. So you have to handle async errors the old fashion way, with a catch function.

function getDataFromDatabase() {
  return new Promise((resolve) => {
    setTimeout(resolve, 250, {canDoStuff: 'yes', canDoSecondStuff: 'yes'});
  });
}
function doAsynchronousStuffIDoNotNeedToAwait() {
  return new Promise((resolve) => {
    setTimeout(resolve, 250);
  });
}
function doSecondAsynchronousStuffIDoNotNeedToAwait() {
  return new Promise((_, reject) => {
    setTimeout(reject, 250, 'error: doSecondAsynchronousStuffIDoNotNeedToAwait()');
  });
}
async function doSomeStuff() {
  try {

    const data = await getDataFromDatabase()
    if(data.canDoStuff == "yes") {
       doAsynchronousStuffIDoNotNeedToAwait()
    }

    if(data.canDoSecondStuff == "yes") {
       doSecondAsynchronousStuffIDoNotNeedToAwait()
          .then(result => console.log("Done!")).catch((err) => console.log(err));
    }

  } catch(err) {
    console.log(err)
  }
}
doSomeStuff();
dotconnor
  • 1,736
  • 11
  • 22
1

It's easy enough to test:

awaiting the value works as expect :

function getDataFromDatabase(){
  return Promise.resolve({canDoStuff: "yes"})
}
function doAsynchronousStuffIDoNotNeedToAwait(){
  return Promise.reject("whoops")
}

async function doSomeStuff() {
  try {

    const data = await getDataFromDatabase()
    if(data.canDoStuff == "yes") {
       let d = await doAsynchronousStuffIDoNotNeedToAwait()
    }
    
  } catch(err) {
    console.log("caught error:", err)
  }
}

doSomeStuff()

Without await you get an uncaught promise rejection error (which I think you can only see on SO if you look in the console):

function getDataFromDatabase(){
  return Promise.resolve({canDoStuff: "yes"})
}
function doAsynchronousStuffIDoNotNeedToAwait(){
  return Promise.reject("whoops")
}

async function doSomeStuff() {
  try {

    const data = await getDataFromDatabase()
    if(data.canDoStuff == "yes") {
       doAsynchronousStuffIDoNotNeedToAwait()
    }
    
  } catch(err) {
    console.log("caught error", err)
  }
}

doSomeStuff()

This makes sense because without await the function doesn't wait for the promise to resolve and the function finishes before there's a chance to catch the rejected promise.

Mark
  • 90,562
  • 7
  • 108
  • 148