是否有映射/串联集合纯粹基于承诺的方法? [英] Is there a pure Promise-based approach for mapping/concatenating collections?

查看:111
本文介绍了是否有映射/串联集合纯粹基于承诺的方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

异步与Q一般

我学习的Node.js开发,并试图环绕管理异步回调地狱战略,我的大脑。我已经探讨了两个主要的战略是Caolan麦克马洪的异步模块,和克里斯科瓦尔的基于承诺-的Q 模块。

许多人的,我仍然在努力理解时,你应该使用一个与其他的。但总的来讲,我发现承诺和基于Q-code是的的更直观,所以我一直在朝这个方向发展。

映射/串联藏品一般

不过,我仍然使用异步模块的功能来管理的集合卡住。从Java和Python背景的,大多数的时候我有收集工作的时候,逻辑是这样的:


  1. 初始化一个新的空收藏,其中存储的结果。

  2. 执行的,每一个与旧收集循环应用一些逻辑的每个元素,推动它的结果到新的空集合。

  3. 当for-each循环结束后,继续使用新的集合。

在客户端的JavaScript,我已经习惯于使用jQuery的 map()函数路过...在步骤#2的逻辑,以及获取步骤#3的结果作为返回值。感觉就像相同的基本方法。

映射/串联与异步和Q

集合

节点端异步模块有类似地图和的 CONCAT 功能,但他们不会在原来的范围级别返回连接结果返回。相反,您必须降入地狱回调使用的结果。例如:

VAR递延= Q.defer();...VAR项= [?] //某些对象数组ID属性async.concat(条目功能(入口,回调){
    回调(NULL,entry.id);
},功能(呃,IDS){
    //我们现在有IDS数组,拿着所有项目的ID属性项数组中为止。
    ...
    // Optionaly,也许是做IDS的一些排序或其他后处理。
    ...
    deferred.resolve(IDS);
});...返回deferred.promise;

由于我等功能正在成为基于承诺-,我有这样的code返回一个承诺对象,以便它可以很容易地包含在则()链。

我真的都需要?

这是我挣扎阐明最终的问题是:我真的需要两个异步在上面的code示例Q?我正在学习如何一般更换Q版造型的诺言链异步模块的控制流......但还没有对我怎么做映射或集合的串联与基于承诺的方式点击。另外,我想知道为什么你不能,或者为什么这不是一个好主意。

如果异步和Q是为了一起工作,因为我在上面的例子中使用它们,那就这样吧。不过,我想preFER不要求额外的库的依赖,如果我能独自干净用Q

很抱歉,如果我想的东西悍然明显。异步事件驱动模型是一个非常不同的世界,我的头还在游泳。的)


解决方案

  

我是否真的需要这两者?


没有。在一个集合映射异步迭代器与承诺很简单,但它需要两个步骤,而不是一个函数调用。首先,集合是<一个href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map\"><$c$c>mapped到的承诺为并行迭代的阵列。然后,这些承诺被送入 Q.all ,以便为映射集合1的承诺。相反,异步,结果的顺序是保证的。

  VAR项= []; //某些对象数组ID属性VAR承诺= entries.map(函数(对象){
    返回asyncPromiseReturingFunction(对象);
}); //匿名包装可以省略
返回Q.all(承诺);

有关 CONCAT ,你将不得不追加

 。然后(功能(结果){
     返回Array.prototype.concat.apply([],结果);
});

async vs. Q generally

I'm learning Node.js development, and trying to wrap my brain around strategies for managing asynchronous "callback hell". The two main strategies I've explored are Caolan McMahon's async module, and Kris Kowal's promise-based Q module.

Like many other people, I'm still struggling to understand when you should use one vs. the other. However, generally speaking I have found promises and Q-based code to be slightly more intuitive, so I have been moving in that direction.

Mapping/Concatenating collections generally

However, I'm still stuck using the async module's functions for managing collections. Coming from a Java and Python background, most of the time when I work with a collection, the logic looks like this:

  1. Initialize a new empty collection, in which to store results.
  2. Perform a for-each loop with the old collection, applying some logic to each element and pushing its result into the new empty collection.
  3. When the for-each loop ends, proceed to use the new collection.

In client-side JavaScript, I've grown accustomed to using jQuery's map() function... passing in that step #2 logic, and getting the step #3 result as a return value. Feels like the same basic approach.

Mapping/Concatenating collections with async and Q

The Node-side async module has similar map and concat functions, but they don't return the concatenated result back at the original scope level. You must instead descend into the callback hell to use the result. Example:

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;

Since my other functions are becoming promise-based, I have this code returning a promise object so it can be easily included in a then() chain.

Do I really need both?

The ultimate question that I'm struggling to articulate is: do I really need both async and Q in the code example above? I'm learning how to replace the async module's control flow with Q-style promise chains generally... but it hasn't yet "clicked" for me how to do mapping or concatenation of collections with a promise-based approach. Alternatively, I'd like to understand why you can't, or why it's not a good idea.

If async and Q are meant to work together as I am using them in the example above, then so be it. But I would prefer not to require the extra library dependency if I could cleanly use Q alone.

(Sorry if I'm missing something outrageously obvious. The asynchronous event-driven model is a very different world, and my head is still swimming.)

解决方案

Do I really need both?

No. Mapping asynchronous iterators over a collection is quite simple with promises, but it requires two steps instead of one function call. First, the collection is mapped to an array of promises for the parallel iteration. Then, those promises are fed into Q.all to make one promise for the mapped collection. In contrast to async, the order of the result is guaranteed.

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);

For concat, you would have to append a

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

这篇关于是否有映射/串联集合纯粹基于承诺的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆