【问题标题】:JS/TS - Returning promise resolved/rejected values inside async functionsJS/TS - 在异步函数中返回承诺已解决/拒绝的值
【发布时间】:2020-01-16 04:57:54
【问题描述】:

我在我的代码中使用了一个函数定义,它是一个异步函数,它通过 try/catch 从 Promise 返回值。像这样的东西:-

async someFunction(parameters) {
  return new Promise(async(resolve, reject) => {
    try {

      // do something like an api call with await and resolve the response
      resolve(parameters);

    } catch (error) {
      reject(error);
    }
  });
}

someFunction("HEllo world");

我想问,这是不是有点矫枉过正?我在写冗余代码吗?这是反模式吗?

【问题讨论】:

  • 取决于do something里面的内容
  • @CertainPerformance 更新了代码。
  • 是的,至少有两种反模式。你不需要声明一个函数async,你只是从中返回一个手动创建的承诺。而且,您也不需要将 Promise executor 回调声明为 async。而且,如果你在 executor 中使用 await,那么你不需要用手动创建的 Promise 来包装它。
  • @jfriend00 如果我在其他地方用 await 调用这个函数怎么办?
  • 在下面查看我的答案。

标签: javascript node.js typescript promise


【解决方案1】:

我想问,这是不是有点矫枉过正?我在写冗余代码吗?这是反模式吗?

是的,它是矫枉过正,它至少有两个,也许三个反模式。

你不需要声明一个函数async,你只是从中返回一个手动创建的promise。而且,您也不需要将 Promise executor 回调声明为 async。而且,如果你在 executor 中使用 await,那么你不需要用手动创建的 Promise 来包装它。

如果您真的打算在 Promise 执行器中使用 await,那么您必须已经拥有返回要使用 await 的 Promise 的函数。如果是这样,那么就没有理由将它们包装在手动创建的 Promise 中。这是一个 Promise 反模式。

您也不需要尝试/捕获,然后以同样的错误拒绝。您可以让错误自行传播。

因此,假设您有两个返回承诺的函数,您希望使用await 串行运行它们。那么,你所需要的就是:

async function someFunction(parameters) {

    let v1 = await func1(...);
    // do something with v1
    let v2 = await func2(someValFromV1);
    // do something with v2
    return someValFromV2;
}

someFunction("HEllo world").then(result => {
    console.log(result);
}).catch(err => {
    console.log(err);
});

或者你可以用await而不是.then()来调用它:

async function anotherFunction() {
    let result = await someFunction(...);
    // do something with result
}

【讨论】:

  • 正如我上面评论的那样,如果我在其他地方用 await 调用这个函数怎么办?然后我应该将函数定义为异步,对吗?此外,我正在 someFunction 内部执行与 DB 相关的任务(大多数 DB ORM 函数返回一个承诺)或外部 API 调用,如果函数失败,我需要返回错误。在这种情况下我该怎么办?有关信息,我正在制作一个 Web 应用程序,我需要在响应中显示错误或返回的值。
  • @Gabriel - 我的回答已经显示最后用await 调用它。这种用文字描述的假设性东西很难做出好的答案。如果您需要更具体的帮助,请向我们展示您的真实代码,我们将能够为您提供非常具体(并且可能很有帮助)的建议。编写异步代码的最佳方法总是特定于您正在做什么,并且需要一本书来涵盖所有理论可能性。但是,如果您向我们展示一段特定的真实代码,可以轻松地向您展示一个好方法。
  • @Gabriel - 我的所有示例都会通过返回的承诺自动传播错误。在 await 错误上被拒绝的承诺会导致从 async 函数返回的承诺自动拒绝,并且调用者会看到带有适当错误的拒绝。只有当你想拦截错误并在它发生时做一些特殊的事情时,你才需要在本地捕获错误,而不是让它自然地传播回调用者。真正的代码更容易讨论。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-01
  • 1970-01-01
相关资源
最近更新 更多