Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript, Node.js: is Array.forEach asynchronous?

I have a question regarding the native Array.forEach implementation of JavaScript: Does it behave asynchronously? For example, if I call:

[many many elements].forEach(function () {lots of work to do}) 

Will this be non-blocking?

like image 210
R. Gr. Avatar asked Feb 19 '11 10:02

R. Gr.


People also ask

Is forEach async node JS?

forEach is not designed for asynchronous code. (It was not suitable for promises, and it is not suitable for async-await.) For example, the following forEach loop might not do what it appears to do: const players = await this.

Is forEach loop synchronous?

Note: forEach expects a synchronous function. forEach does not wait for promises. Make sure you are aware of the implications while using promises (or async functions) as forEach callback.

Is NodeJS asynchronous or synchronous?

NodeJS is an asynchronous event-driven JavaScript runtime environment designed to build scalable network applications. Asynchronous here refers to all those functions in JavaScript that are processed in the background without blocking any other request.

Is JavaScript forEach sequential?

forEach calls a provided callback function once for each element in an array in ascending order. Callback runs in sequential but it does not wait until one is finished. That is because it runs not like iteration which runs next step when one step is finished.


2 Answers

No, it is blocking. Have a look at the specification of the algorithm.

However a maybe easier to understand implementation is given on MDN:

if (!Array.prototype.forEach) {   Array.prototype.forEach = function(fun /*, thisp */)   {     "use strict";      if (this === void 0 || this === null)       throw new TypeError();      var t = Object(this);     var len = t.length >>> 0;     if (typeof fun !== "function")       throw new TypeError();      var thisp = arguments[1];     for (var i = 0; i < len; i++)     {       if (i in t)         fun.call(thisp, t[i], i, t);     }   }; } 

If you have to execute a lot of code for each element, you should consider to use a different approach:

function processArray(items, process) {     var todo = items.concat();      setTimeout(function() {         process(todo.shift());         if(todo.length > 0) {             setTimeout(arguments.callee, 25);         }     }, 25); } 

and then call it with:

processArray([many many elements], function () {lots of work to do}); 

This would be non-blocking then. The example is taken from High Performance JavaScript.

Another option might be web workers.

like image 100
Felix Kling Avatar answered Sep 18 '22 05:09

Felix Kling


If you need an asynchronous-friendly version of Array.forEach and similar, they're available in the Node.js 'async' module: http://github.com/caolan/async ...as a bonus this module also works in the browser.

async.each(openFiles, saveFile, function(err){     // if any of the saves produced an error, err would equal that error }); 
like image 32
Caolan Avatar answered Sep 19 '22 05:09

Caolan