Home > Enterprise >  Am I over-nesting in JavaScript Async/Await
Am I over-nesting in JavaScript Async/Await

Time:04-28

I am developing a React App (This is not important, because what I am going to explain can happen in other situations as well.)

I have three asynchronous functions, let's call them func1 and func2, and func3 and this is how they look. This is the general pattern of these functions.

const func1 = async ()=>{
    try {
        // do something
        const resultForFunc2 = // the end result of doing something that is going to be used in func2
        return {statusCode: 200, body: resultForFunc2, error: null}
    } catch(err) {
        console.log("Error in executing func1", err)
        return {statusCode: 400, body: null, error: err}
    }
}

Now the way these functions are called is that func1 returns a value that is used in func2 and func2 returns a value that is used in func3.

So this is how I call them:

const all = async () => {
  const response1 = await func1();
  if (response.statusCode === 200) {
      const response2 = await func2(response1);
      if (response2.statusCode === 200) {
          const response3 = await func3(response2);
          if (response3.statusCode === 200) {
              return { statusCode: 200, body: response3.body, error: null };
          } else {
              return { statusCode: 400, error: response3.error, body: null };
          }
      } else {
        return { statusCode: 400, error: response2.error, body: null };
      } 
  } else {
      return { statusCode: 400, error: response.error, body: null };
  }
}
 

This works for me because I call the above all function in a React component, in a useEffect() for example, and whenever I get a 400 statusCode I set an error state variable to true and then display an error screen (I came up with this idea, so feel free to criticize it, I appreciate it actually). But the bad thing is that I have so many nested ifs that make the code ugly, dirty, and hard to read and debug. Does anyone have an idea how I can get the benefits of the above code block, without using nested ifs. Thank you.

CodePudding user response:

Maybe try this approach. I did not test it, but i guess it should help you

const all = async () => {
  let funcs = [func1, func2, func3];
  let res;
  for (const f of funcs) {
    let { statusCode, body, error } = await f();
    if (statusCode !== 200) return { statusCode, error };
    res = body;
  }
  return res;
};

CodePudding user response:

This might be a good question for code review

I have two ideas for reducing nesting. One is using a catch function instead of try catch blocks, i.e.

const err = e => console.error(e);

const func1 = async () => {
    // do something
    const resultForFunc2 = // the end result of doing something that is going to be used in func2
    return {statusCode: 200, body: resultForFunc2, error: null}
}

const result1 = await func1.catch(err);

Another idea is to exit on a fail instead of nest the continuing code inside a block. i.e.

const all = async () => {
  const response1 = await func1().catch(err);
  if (response.statusCode !== 200) return { statusCode: 400, error: response.error, body: null };
  const response2 = await func2().catch(err);
  if (response2.statusCode !== 200) return { statusCode: 400, error: response2.error, body: null };
  //and so on
}
  • Related