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?
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.
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.
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.
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.
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.
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 });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With