异步与 Q 通常
我正在学习 Node.js 开发,并试图围绕管理异步“回调地狱”的策略展开思考。我探索的两个主要策略是 Caolan McMahon 的async模块和 Kris Kowal 的基于 promise 的Q模块。
像许多其他人一样,我仍在努力理解何时应该使用一个与另一个。但是,一般来说,我发现 Promise 和基于 Q 的代码更直观一些,所以我一直在朝着这个方向前进。
通常映射/连接集合
但是,我仍然坚持使用 async 模块的功能来管理集合。来自 Java 和 Python 背景,大多数时候我使用集合时,逻辑如下所示:
- 初始化一个新的空集合,用于存储结果。
- 对旧集合执行 for-each 循环,对每个元素应用一些逻辑并将其结果推送到新的空集合中。
- 当 for-each 循环结束时,继续使用新的集合。
在客户端 JavaScript 中,我已经习惯于使用 jQuery 的map() 函数……传入第 2 步的逻辑,并将第 3 步的结果作为返回值。感觉就像是相同的基本方法。
使用 async 和 Q 映射/连接集合
节点端异步模块具有类似的map和concat函数,但它们不会将连接的结果返回到原始范围级别。您必须改为进入回调地狱才能使用结果。例子:
var deferred = Q.defer();
...
var entries = [???]; // some array of objects with "id" attributes
async.concat(entries, function (entry, callback) {
callback(null, entry.id);
}, function (err, ids) {
// We now have the "ids" array, holding the "id" attributes of all items in the "entries" array.
...
// Optionaly, perhaps do some sorting or other post-processing on "ids".
...
deferred.resolve(ids);
});
...
return deferred.promise;
由于我的其他函数正变得基于 Promise,因此我让这段代码返回一个 Promise 对象,以便它可以轻松地包含在then()
链中。
我真的需要两者吗?
我正在努力表达的最终问题是:在上面的代码示例中,我真的需要 async和Q 吗?我正在学习如何用 Q 风格的承诺链替换异步模块的控制流......但它还没有“点击”我如何使用基于承诺的方法进行集合的映射或连接。或者,我想了解您为什么不能,或者为什么这不是一个好主意。
如果我在上面的示例中使用 async 和 Q 是为了一起工作,那么就这样吧。但如果我可以单独使用 Q,我宁愿不需要额外的库依赖项。
(对不起,如果我遗漏了一些非常明显的东西。异步事件驱动模型是一个非常不同的世界,我的脑袋还在游泳。)