3

Is there some framework similar to underscore that allows me to run async methods on collections.

Something like _.each(collection, itemCallback, doneCallback).

For example:

_.each(items, function(item, token){
    item.someProperty = null;
  }, function(err){
     console.log("The loop is done");
  });

Edit: async.js actually doesn't solve the problem. For example the following code

<script type="text/javascript" src="async.js"></script>
<script type="text/javascript">

var arr = ["a","b","c"];

async.forEach(arr, function(item, met){
    console.log(item);
},
function(err){
});
console.log("Done");

</script>

prints a b c Done

While I want it to print Done a b c

I can do it with underscore deffer but maybe there is some other lib that can do it without wrappers.

2
  • 2
    Async.js to the rescue. :) It's funny that you used async name and didn't know about async module. :) Commented Jul 16, 2012 at 10:22
  • You are right :). I am using Async.js for control flow and somehow I missed the collections section entirely. Commented Jul 16, 2012 at 10:28

1 Answer 1

18

Async.js module will do the trick. Your example is just too fast for you to fully notice it is actually working as you will expect. Here is an example with a small delay added so you can notice the actual order of execution:

async.each([0,1,2,3,4,5,6,7,8,9], function(item, callback) {
  setTimeout(function() {
    console.log('>', item);
    callback();
  }, 2 * Math.random() * 1000);
}, function(err) {
  console.log('> done');
});

console.log(':)');

And the output:

:)
> 4
> 5
> 2
> 7
> 8
> 3
> 0
> 1
> 9
> 6
> done

Also, to really do it asynchronous you might consider to use Web Workers; but for now Async.js provides you a really simple way to do something similar (but not actual Web Workers) named queue:

var q = async.queue(function(item, callback) {
  setTimeout(function() {
    console.log('>>', item);
    callback();
  }, 2 * Math.random() * 1000);
}, 5);

q.drain = function() {
  console.log('>> done');
};

q.push([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);

console.log('B)');

And the output:

B)
>> 1
>> 2
>> 5
>> 6
>> 4
>> 3
>> 0
>> 7
>> 8
>> 9
>> done

And if finally you run both simultaneously, here is an example of the output:

:)
B)
>> 2
> 3
>> 4
>> 1
> 8
>> 6
> 7
> 1
> 4
>> 3
> 0
> 2
>> 7
>> 5
> 6
> 5
> 9
> done
>> 8
>> 0
>> 9
>> done
Sign up to request clarification or add additional context in comments.

3 Comments

This answer seems to be deprecated. The Async.js docs don't say anything about a async.forEach function.
@bzupnick its just called Each now. Thanks Erick for the explanation.
Yep I bet they changed it to get distance from native forEach that actually blocks I/O

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.