0

I'm looking at using ES5's new Array.forEach(). I believe the callbacks for each item should execute in parallel. I'd like a function to return once all values have processed.

// I'd like to make parent_function return a new array with the changed items.
function parent_function(array_of_things) {
    new_array = []
    array_of_things.forEach( function(thing) {
        new_array.push('New '+thing)
        if ( new_array.length === array_of_things.length ) {
            // OK we've processed all the items. How do I make parent_function return the completed new_array? 
            return new_array
        }
    })
}

I suspect that this may be the wrong approach: because the parent_function may finish before every callback has been fired. In this case, firing a custom event (that's handled by whatever needs the data produced after we've processed all the items) may be the best approach. However I didn't find any mention of that in the MDC docs.

But I'm fairly new to JS and would love some peer review to confirm!

Edit: Looks like forEach() is synchronous after all. I was logging the resulting array afterwards and seeing inconsistent results - sometimes two items, sometimes four, etc, which made me think it was async. If you're reading this and having similar behaviour, I suggest you read this item about issues in Chrome's array logging.

Community
  • 1
  • 1
mikemaccana
  • 110,530
  • 99
  • 389
  • 494

2 Answers2

1

Nope, all these iterator functions are synchronous. That means, the callbacks are executed one after the other each with the next item, then in the end forEach() returns (and returns undefined).

If you want a new_array with the results of each callback invokation, you'd have a look at map().

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Thanks - I've found http://stackoverflow.com/questions/5050265/javascript-nodejs-is-array-foreach-asynchronous which has a reference for it being syncronous to confirm your answer. Is map() the **only** solution to get a new_array with all the modified items in it? – mikemaccana Apr 10 '12 at 20:09
  • What other solution would you seek for? Of course you can always build a new array manually while iterating (elegant solution uses [reduce](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/Reduce)). – Bergi Apr 10 '12 at 20:19
1

The forEach() call is synchronous, you can just return the new Array when the forEach() is finished:

function parent_function(array_of_things) {
  var new_array = [];
  array_of_things.forEach(function(thing) {
    new_array.push('New '+thing);
  });
  return new_array;
}
  • Hehe thanks. I think I just assumed async due to some other odd behaviour. http://ecma262-5.com/ELS5_HTML.htm#Section_15.4.4.18 mentions the sync behaviour. – mikemaccana Apr 10 '12 at 20:22