【问题标题】:Can I mix callbacks and async/await patterns in NodeJS?我可以在 NodeJS 中混合使用回调和异步/等待模式吗?
【发布时间】:2020-05-27 06:58:39
【问题描述】:

我在互联网上寻找答案,但我无法真正找到我想要的东西。

我需要知道以下代码有什么问题(前提是我们应该避免混淆回调和承诺)-

function a(callback){
    (async ()=>{
        try{
           let result = await doSomething();
           callback(null, result);
        } catch(e){
           log('error at await');
           callback(e, null);
        }
    })()
}

如果我在代码中使用上述模式可以吗?

【问题讨论】:

  • 不推荐。在混合回调和承诺时,通常更难以进行正确的错误处理。此外,控制流可能是一团糟。这个例子并不算太混乱,因为只有一个异步操作,但为什么不直接返回一个 Promise 并加入现代异步设计时代并完全跳过使用任何普通回调呢?此外,这里的await 毫无意义。您刚刚使事情变得比return doSomething() 复杂得多,并让调用者使用返回的承诺。
  • 它的问题在于它的方式比需要的复杂得多。一个简单的return doSomething() 并让调用者使用返回的承诺替换所有这些。
  • 我明白你的意思。非常感激。 @jfriend00

标签: node.js async-await callback


【解决方案1】:

我可以在 NodeJS 中混合使用回调和异步/等待模式吗?

你可以。不推荐。

在混合回调和承诺时,通常更难进行正确的错误处理。此外,控制流可能是一团糟。这个例子并不太混乱,因为只有一个异步操作,但为什么不直接返回一个 Promise 并加入现代异步设计时代并完全跳过使用任何普通回调呢?此外,这里的等待是毫无意义的。您刚刚使事情变得比return doSomething() 复杂得多,并让调用者使用返回的承诺。

因此,您可以将 9 行函数体(包括 async IIFE)替换为 1 行简单的代码。

不混合普通回调和承诺的原因

  1. 首先,使用 Promise 而非普通回调的所有理由。我不会重复所有这些,因为它们已经被分析和重复了很多次。引入任何简单的回调只会否定很多首先使用 Promise 的原因。
  2. 100% 基于 Promise 的代码通常比两者的任何组合都更紧凑、更简单(一旦您了解了 Promise 以及如何最好地编写它们)。
  3. 混合使用 Promise 和普通回调时,控制流会变得非常复杂。每个人都有一个如何做到这一点的模型。只要您有多个并行或顺序异步操作,普通回调就会复杂得多(这就是为什么当我们只有普通回调时必须存在诸如 async 库之类的库的原因),而这种级别的流控制是自然的和内置的-承诺。然后,尝试混合控制流和错误处理这两种模型,事情很快就会变得非常复杂。
  4. 许多开发人员在尝试将两者混合时在错误处理方面犯了错误,未能正确传播错误。出现这些错误的原因是,在混音时正确操作会更加复杂。
  5. Promise 是 Javascript/nodejs 中异步编程的现在和未来。我们甚至很快就会拥有顶级await,甚至可能会基于承诺进行异步导入。您为什么要使用不再被认为是该语言的现在或未来的旧模型来增加复杂性。
  6. 如果您有一些不返回 Promise 的异步操作,那么您可以通过在它们周围放置一个 Promise 包装器(可能使用util.promisify())来更恰当地使用它们,然后仅在它们的 Promise 形式中使用它们以用于您的实际实现和控制流。

【讨论】:

  • 你的回答太好了,我只想删除我的哈哈。我想关键是,如果你真的需要混合它们,你可以,但在大多数情况下,这不会被认为是最佳实践。顺便说一句,我的旧 SO 帐户一直是前 0.02%。我失去了访问权限,所以重新开始 :( 哈哈
  • 明白。谢谢。解释得很透彻。
  • 我还没有退休,所以我必须将我的年限减半,这样人们就不会认为我太老了,无法学习新技巧,哈哈(
猜你喜欢
  • 2020-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-30
  • 2020-07-11
  • 1970-01-01
  • 2016-02-23
相关资源
最近更新 更多