Node.js控制流程:回调还是承诺?

nab*_*nab 18 control-flow node.js

我知道node.js 有很多控制流库.其中一些让一个链异步函数与回调(如async,asyncblock等),其他使用promise概念(Q,延期,期货等).鉴于长时间运行的脚本会一个接一个地执行一系列可能随时失败的操作,您更喜欢哪种控制流程?为什么?优缺点都有什么?

joe*_*dle 13

回调的优点:

  • 简单易懂和创造.
  • 有点更高效,因为创建较少的对象和垃圾收集.
  • Node (error,result)始终选择回调.我建议遵循他们的参数顺序以保持一致性 (与之相反(result1, result2, result3, error).)

承诺的优点:

  • 提供流畅的界面,有时可以帮助缓解嵌套的回调地狱,如下所示.代码似乎通过链接.then(foo).then(bar)调用线性流动.
  • 一个好的promises库可以让你并行运行许多异步操作,并且只有在它们全部完成时才继续.该递延库做这种无缝通过map,Q具有allResolved和ES6承诺提供Promise.all().(这也可以通过回调来实现,例如使用async.parallel(),但不是内置的.)
  • 一个好的promises库将允许您指定一个错误处理函数,如果任何排队函数失败,将调用该函数.要使用回调执行此操作需要一些样板:if (err) return callback(err);在每个回调开始时.

对于将每秒运行多次的代码,在堆栈底部附近使用回调是有意义的.堆栈越高,承诺可能更好,因为它们更容易阅读和理解,并且可以更优雅地处理错误.

值得注意的是,promises可以在运行时从回调构建.因此,您可以在极简主义回调表单中实现核心代码,并且如果您愿意,仍然会公开该库的promises版本.(如Q.nfbind().)

我很想知道其他优点/缺点.

额外提示:始终处理错误!使用这两种方法,如果你不处理错误,它就会消失,让你不知道为什么你的代码没有按预期工作.

回调应始终处理if (err) ...,.catch()如果不返回,Promise应始终具有.

即使您有时期望错误,也不需要处理错误,但不处理意外错误意味着如果将来更改代码,您将不会听到开发人员错误(如拼写错误)中的错误.

.catch()Promise 的另一种选择是倾听未经处理的拒绝.我个人用这个来发出一个.catch()丢失的警告!


Ste*_*ell 5

我不认为有很多客观的利弊.异步非常受欢迎(基于依赖它的 npm ).

我喜欢控制流库(特别是异步),因为我更容易理解.承诺使我感到困惑,而异步很容易理解.我怀疑它只是一个学习曲线的东西,如果我花了很多钱去学习它们,那么承诺会更具可读性.但是,我是否应该期待那些尝试阅读我的代码的人呢?

还有第三种类型 - 纤维.光纤在Windows上不起作用,但(IMO)为应该串行执行的事物提供了最清晰的语法.