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

Ste*_*ins 17 javascript asynchronous node.js promise q

一般是异步与Q

我正在学习Node.js开发,并试图围绕管理异步"回调地狱"的策略.我探索的两个主要策略是Caolan McMahon的异步模块和Kris Kowal的基于承诺的Q模块.

许多其他人一样,我仍然在努力理解何时应该使用其中一个.但总的来讲,我发现承诺和基于Q-代码要稍微更直观,所以我在这个方向被移动.

通常映射/连接集合

但是,我仍然坚持使用异步模块的功能来管理集合.来自Java和Python背景,大部分时间我使用集合时,逻辑如下所示:

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

在客户端JavaScript中,我已经习惯于使用jQuery的map()函数 ...传递步骤#2逻辑,并将步骤#3结果作为返回值.感觉像是一样的基本方法.

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

节点端异步模块具有类似的mapconcat函数,但它们不会在原始作用域级别返回连接结果.你必须转而进入回调地狱才能使用结果.例:

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;
Run Code Online (Sandbox Code Playgroud)

由于我的其他函数正在变为基于承诺,因此我将此代码返回一个promise对象,以便它可以轻松地包含在then()链中.

我真的需要两者吗?

我正在努力阐述的最终问题是:在上面的代码示例中,我是否真的需要async Q?我正在学习如何通常用Q风格的承诺链替换async模块的控制流......但它还没有"点击"我如何使用基于承诺的方法进行集合的映射或连接.或者,我想了解为什么你不能,或者为什么它不是一个好主意.

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

(对不起,如果我遗漏了一些非常明显的东西.异步事件驱动的模型是一个非常不同的世界,我的脑子还在游泳.)

Ber*_*rgi 27

我真的需要两者吗?

使用promises,在集合上映射异步迭代器非常简单,但它需要两个步骤而不是一个函数调用.首先,集合mapPED以承诺为并行迭代的阵列.然后,这些承诺被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);
Run Code Online (Sandbox Code Playgroud)

因为concat,你必须附加一个

.then(function(results) {
     return Array.prototype.concat.apply([], results);
});
Run Code Online (Sandbox Code Playgroud)