是否有纯粹的基于Promise的方法来映射/连接集合?

asynchronous与Q一般

我正在学习Node.js开发,并试图围绕pipe理asynchronous“callback地狱”的策略包装我的大脑。 我探索的两个主要策略是Caolan McMahon的asynchronous模块和Kris Kowal的基于承诺的Q模块。

像许多其他人一样,我仍然在努力去理解什么时候应该使用一个而不是另一个。 但是,总的来说,我已经发现许诺和基于Q的代码稍微直观一点,所以我一直在朝着这个方向前进。

一般地映射/连接集合

不过,我仍然坚持使用asynchronous模块的function来pipe理集合 。 从Java和Python的背景来看,大多数时候我使用一个集合,逻辑如下所示:

  1. 初始化一个新的空集合,在其中存储结果。
  2. 对旧集合执行for-each循环,对每个元素应用一些逻辑并将结果推送到新的空集合中。
  3. 当for-each循环结束时,继续使用新的集合。

在客户端JavaScript中,我习惯于使用jQuery的map()函数 …传递第2步的逻辑,并将第3步的结果作为返回值。 感觉像相同的基本方法。

使用asynchronous和Q映射/连接集合

节点端asynchronous模块具有相似的映射和连接function,但是它们不会将连接结果返回到原始范围级别。 你必须下降到callback地狱使用结果。 例:

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; 

由于我的其他function正在成为基于承诺,我有这个代码返回一个承诺对象,所以它可以很容易地包含在一个then()链。

我真的需要两个吗?

我努力expression的最终问题是:在上面的代码示例中,我真的需要async Q吗? 我正在学习如何用Q风格的承诺链来replaceasynchronous模块的控制stream…但是它还没有“点击”我如何使用基于承诺的方法进行集合的映射或级联。 另外,我想了解为什么你不能,或者为什么它不是一个好主意。

如果asynchronous和Q是为了一起工作,因为我在上面的例子中使用它们,那就这样吧。 但是我宁愿不要求额外的库依赖,如果我可以干净地单独使用Q.

对不起,如果我失去了一些显而易见的东西,asynchronous的事件驱动的模式是一个非常不同的世界,我的头仍在游泳。

我真的需要两个吗?

不。在集合上映射asynchronous迭代器是非常简单的,但需要两个步骤而不是一个函数调用。 首先,将集合map到并行迭代的promise数组。 然后,这些承诺被送到Q.all为映射集合作出一个承诺。 与async ,结果的顺序是有保证的。

 var entries = […]; // some array of objects with "id" attributes var promises = entries.map(function(object) { return asyncPromiseReturingFunction(object); }); // the anonymous wrapper might be omitted return Q.all(promises); 

对于concat ,你将不得不追加一个

 .then(function(results) { return Array.prototype.concat.apply([], results); });