2012-02-22 64 views

回答

5

我不认为有很多客观的优点和缺点。异步非常流行(基于npm packages that depend on it)。

我喜欢控制流库(特别是异步),因为它更容易理解。承诺混淆了我,而异步很容易理解。我怀疑它只是一个学习曲线的东西,如果我花费精力去学习它,承诺会更具可读性。但是,我是否应该期望那些试图阅读我的代码的人呢?

还有第三种 - Fibers。 Fibers不能在Windows上工作,但(IMO)为应该以串行方式执行的事情提供最清晰的语法。

13

优点回调:

  • 简单理解和创造。
  • 有点效率更高,因为更少的对象被创建和垃圾收集。
  • 节点选择了(error,result)整个回调。我建议遵循他们的论证顺序来保持一致。 (而不是说(result1, result2, result3, error)

优点的承诺:

  • 提供一个流畅的界面,有时可以帮助减轻嵌套回调地狱,如shown here。代码似乎通过链接.then(foo).then(bar)调用线性流动。
  • 一个好的承诺库可以让你在并行上运行很多异步操作,并且只有在它们全部完成后才能继续。 Deferred库通过map无缝地完成此操作,Q具有allResolved,ES6承诺报价Promise.all()。 (这也可以使用回调,例如使用async.parallel(),但不是内置。)
  • 一个好的承诺库将让你指定一个错误处理函数,如果任何排队的函数失败将被调用。要使用回调来做到这一点,需要在每个回调开始时使用一点样板:if (err) return callback(err);

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

值得注意的是,承诺可以在运行时从回调构建。因此,您可以用最低限度的回调形式实现您的核心代码,并且如果您愿意,仍然可以公开库的承诺版本。 (如在Q.nfbind()。)

我很想听听其他优点/缺点。

奖励建议:总是处理错误!使用这两种方法,如果您不处理错误,那么它将简单地消失,让您在黑暗中为什么代码无法按预期工作。

回调应始终处理if (err) ...和承诺应始终有.catch()如果他们不返回。

即使你期望的错误有时,并不需要处理那些不处理意外的错误意味着你不会听到来自开发商的错误错误,如拼写错误,如果代码在未来发生变化。

Promises的替代.catch()的是听取unhandled rejections。我个人使用这个来发出警告,.catch()失踪!

+1

关于perfs的更多信息:http://thanpol.as/javascript/promises-a-performance-hits-you-should-be-aware-of/ – Offirmo 2013-09-17 12:59:54

+0

链接不再工作 – Shide 2017-01-25 09:13:06

+1

这是[archived copy of Offirmo的PERF链接](http://web.archive.org/web/20160522044854/http://thanpol.as/javascript/promises-a-performance-hits-you-should-be-aware-of)。 – joeytwiddle 2017-01-25 10:35:56

0

我一直在尝试与此库声明的方式:http://chainsjs.org仍然更多的工作做就可以了,但它给你定义一个“执行地图”在这里你几乎可以完全控制流量的能力从简单的映射执行。

+0

那个网站已经关闭,但今天我在档案中找到[副本](http://web.archive.org/web/20141217011058/http://chainsjs.org/)。有一个其他控制流库的列表[这里](https://github.com/joyent/node/wiki/modules#user-content-wiki-async-flow)。 – joeytwiddle 2015-07-02 09:39:23

+0

@joeytwiddle - 感谢您的提示,当github页面更改IP时,我从未切换过IP。我刚刚更新了DNS,它应该很快就会备份。 – 2015-07-10 20:17:40