我知道node.js有很多control flow libraries。其中一些使用回调(例如async,asyncblock等)让一个链异步函数,其他使用promise concept(Q,延期,期货等)。鉴于长时间运行的脚本会一个接一个地执行一系列可能会失败的操作,您更喜欢哪种控制流程,为什么?优缺点都有什么?Node.js控制流:回调还是承诺?
回答
我不认为有很多客观的优点和缺点。异步非常流行(基于npm packages that depend on it)。
我喜欢控制流库(特别是异步),因为它更容易理解。承诺混淆了我,而异步很容易理解。我怀疑它只是一个学习曲线的东西,如果我花费精力去学习它,承诺会更具可读性。但是,我是否应该期望那些试图阅读我的代码的人呢?
还有第三种 - Fibers。 Fibers不能在Windows上工作,但(IMO)为应该以串行方式执行的事情提供最清晰的语法。
优点回调:
- 简单理解和创造。
- 有点效率更高,因为更少的对象被创建和垃圾收集。
- 节点选择了
(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()
失踪!
我一直在尝试与此库声明的方式:http://chainsjs.org仍然更多的工作做就可以了,但它给你定义一个“执行地图”在这里你几乎可以完全控制流量的能力从简单的映射执行。
那个网站已经关闭,但今天我在档案中找到[副本](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
@joeytwiddle - 感谢您的提示,当github页面更改IP时,我从未切换过IP。我刚刚更新了DNS,它应该很快就会备份。 – 2015-07-10 20:17:40
- 1. 回调还是承诺?
- 2. Node.js - 承诺和回调VS同步
- 3. Node.js承诺请求返回
- 4. 节点承诺控制流程
- 5. 解决承诺在服务中没有控制器回调
- 6. 回复承诺的承诺
- 7. 承诺是单播还是广播?
- 8. Node.js Wit.ai承诺返回函数
- 9. node.js解析承诺并返回值
- 10. AngularJS承诺没有回调?
- 11. 蓝鸟承诺和回调
- 12. ES6承诺结算回调?
- 13. NodeJS:承诺内的回调
- 14. 从承诺中回报价值:回调或承诺?
- 15. 承诺链接+返回变量与流星回调
- 16. Node.js控制流程
- 17. 我如何将这个承诺交还给控制器?
- 18. 控制回调流程
- 19. 然后()回调发射之前承诺解决在node.js
- 20. 通过node.js + Q进行同步回调延迟/承诺模块
- 21. Node.js&co - 避免混合承诺和事件回调
- 22. 快速Node.JS - 接收Redis回调,执行承诺
- 23. 使用Bluebird在承诺中包装Node.js回调
- 24. Javascript承诺:catch流
- 25. 流星与承诺?
- 26. 如何退还承诺
- 27. 等待承诺退还
- 28. 如何退还承诺?
- 29. 蓝鸟承诺作为承诺回调不知道api
- 30. 解析承诺数组node.js
关于perfs的更多信息:http://thanpol.as/javascript/promises-a-performance-hits-you-should-be-aware-of/ – Offirmo 2013-09-17 12:59:54
链接不再工作 – Shide 2017-01-25 09:13:06
这是[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