-
-
Save neilk/5380684 to your computer and use it in GitHub Desktop.
/** | |
* Allow other processes to execute while iterating over | |
* an array. Useful for large arrays, or long-running processing | |
* | |
* @param {Function} fn iterator fed each element of the array. | |
* @param {Function} next executed when done | |
*/ | |
Array.prototype.nonBlockingForEach = function(fn, next) { | |
var arr = this; | |
var i = 0; | |
var len = arr.length; | |
function iter() { | |
if (i < len) { | |
fn(arr[i]); | |
i++; | |
process.nextTick(iter); | |
} else { | |
next(); | |
} | |
} | |
iter(); | |
}; |
Hello!
I've tryed this function, iterating over an array with a bilion of undefined elements (new Array(1000000000)),
inside one of my express js route handler, but when i try to visit that specific endpoint (for example /news, which handler start the long iteration), the all application is blocked, and other endpoints does not respond.
What am I missing?
G.
@gabrieledarrigo, the documentation for process.nextTick says
Note: the nextTick queue is completely drained on each pass of the event loop before additional I/O is processed. As a result, recursively setting nextTick callbacks will block any I/O from happening, just like a while(true); loop.
This is exactly what this function is doing so no wonder your express end points are not responding.
Use setImmediate instead of process.nextTick
I was about to mention that you can use promises with existing Array builtins, but both that and the Async library are missing the point. The point is to free up CPU cycles during the iteration itself, under the assumption that the collection is large enough to cause the iteration itself to be slow.