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

Cod*_*how 3 callback node.js async-await

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

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

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

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

jfr*_*d00 7

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

你可以。不推荐。

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

因此,您可以用 1 行简单代码替换 9 行函数体(包括asyncIIFE)。

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

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