【问题标题】:How to combine async/await with Promises?如何将 async/await 与 Promises 结合使用?
【发布时间】:2021-12-15 11:21:36
【问题描述】:

在下面的代码中,我在 async 函数内有 createPost(),但我不想在其上使用 await,因此它会阻止函数其余部分的执行。这就是我使用then的原因。

外部async函数有很多其他函数使用await,所以不能更改。

问题

因为createPost()async/await 函数(见下文)。如何解析/拒绝外部函数中的then/catch

module.exports = async (p) => {
  // lots of code here
  
 const t = await function1();      

    // lots of code here
    createPost(p).then(message => {
      // lots of code here
      console.log("ok " + message);
    }).catch(message => {
      console.log("failed " + message);
    });
};

createPost()

module.exports = async (p) => {
  // lots of code here
  try {
    const r = await getStat();
  } catch (error) {
    console.log(error);
  };
};

【问题讨论】:

  • 为什么第一个模块是async
  • 很遗憾我不明白你的问题,你能描述更多...你想做什么?
  • createPost() 中的 try-catch 块将捕获您的异常,因此您可以删除 createPost() 级别的 try-catch,这样任何错误都会导致返回被拒绝的承诺,并且然后在.catch() 内处理
  • @SandraSchlichting "我需要对createPost() 进行哪些更改,以便可以在外部函数中使用then/catch" - 呃,没有? async function 总是返回一个承诺,你可以简单地调用 .then() 。 “我如何指定外部函数获取的message” - 好吧,你的createPost 实现没有return 任何东西,所以承诺总是解析为undefined。跨度>
  • @Bergi 谢谢。如果我可以将您的评论标记为答案,我会这样做 =)

标签: javascript node.js ecmascript-6 async-await


【解决方案1】:

如果您没有在内部使用 await 关键字,则函数上的 async 声明是多余且错误的。

await/async 通常被称为语法糖,让我们等待某些东西(例如 API 调用),让我们在实际的异步代码中产生同步的错觉,这是一个很大的好处。

你想通过 async/await 实现的事情可以通过 Promise 实现,但 async/await 具有优势。让我们以这段代码为例:

const makeRequest = () => //promise way
  getJSON()
    .then(data => {
      return data
    })

makeRequest();

const makeRequest = async () => { //async await way
  const data = await getJSON();
  return data;
 }

makeRequest()

为什么 async/await 比 promise 更受欢迎?

  1. 简洁明了 - 我们不必编写 .then 并创建一个匿名函数来处理响应,或者为我们不需要使用的变量提供名称数据。我们还避免了嵌套代码。 async/await 更加简洁。

  2. 错误处理 - Async/await 最终可以使用相同的 try/catch 格式处理同步和异步错误。

  3. 调试 - 使用 async/await 的一个非常好的优势是它比 promise 更容易调试,原因有两个:1)您不能在返回表达式的箭头函数中设置断点(不身体)。 2) 如果您在 .then 块内设置断点并使用调试快捷方式(如 step-over),调试器将不会移动到以下 .then ,因为它只会“步进”同步代码。

  4. 错误堆栈 - 从 Promise 链返回的错误堆栈让我们不知道错误发生在哪里,并且可能会产生误导。 async/await 为我们提供了从 async/await 指向包含错误的函数的错误堆栈,这是一个非常大的优势。

【讨论】:

  • 我现在更新了 OP,在这里我解释了为什么我在外部函数中有 async。所以也许问同样问题的另一种方式是:我如何指定外部函数获取的message
【解决方案2】:

async / await.then / .catch 的更现代等价物。
在这种情况下,您混合了两者的语法。
使用 .then 时不需要 try / catch 块,
就像您在使用 try / catch 语法时不需要将函数声明为 async 一样。

除此之外,它们没有理由不能在单独的功能中协同工作。

module.exports = (p) => {
  createPost(p).then(message => {
    console.log("ok " + message);
  }).catch(message => {
    console.log("failed " + message);
  });
};

createPost():

module.exports = async (p) => {
  try {
    const r = await getStat();
  } catch (error) {
    console.log(error);
  };
};

【讨论】:

  • 外部函数中还有其他函数使用await,所以必须使用async。这如何改变你的答案?
  • 那么在这种情况下,您确实需要保留async 以使await 工作,这应该没有问题。虽然我建议一般坚持使用一种方法,除非有任何明确的理由同时使用这两种方法。我认为从长远来看,这会减少混乱。
  • 好的,非常好。我可以像在 Promise resolve() / reject() 函数中那样指定message 的内容吗?
猜你喜欢
  • 1970-01-01
  • 2019-06-09
  • 2015-12-25
  • 2020-08-27
  • 2018-07-18
  • 2019-12-21
  • 1970-01-01
  • 2021-07-21
  • 2019-08-09
相关资源
最近更新 更多