我是否过度嵌套 JavaScript Async/Await

Am I over-nesting in JavaScript Async/Await

我正在开发一个 React 应用程序(这并不重要,因为我要解释的内容也可能发生在其他情况下。)

我有三个异步函数,我们称它们为 func1func2,以及 func3,这就是它们的样子。这是这些函数的一般模式。

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}
    }
}

现在调用这些函数的方式是 func1 returns 在 func2 中使用的值和 func2 returns 中使用的值用于 func3.

所以我是这样称呼它们的:

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 };
  }
}
 

这对我有用,因为我在 React 组件中调用了上面的 all 函数,例如在 useEffect() 中,每当我得到 400 statusCode 时我都会设置错误状态变量 true 然后显示一个错误屏幕(我想出了这个主意,所以请随意批评它,我实际上很感激)。但糟糕的是,我有太多嵌套的 if,这让代码变得丑陋、肮脏,而且难以阅读和调试。有谁知道我如何在不使用嵌套 if 的情况下获得上述代码块的好处。谢谢。

也许试试这个方法。我没有测试它,但我想它应该对你有帮助

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;
};

code review

这可能是个好问题

我有两个减少嵌套的想法。一种是使用 catch 函数而不是 try catch 块,即

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);

另一个想法是在失败时退出,而不是将继续的代码嵌套在一个块中。即

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
}