Основываясь на @ jfriend00, вот прототип версии:
if (Array.prototype.forEachAsync == null) {
Array.prototype.forEachAsync = function forEachAsync(fn, thisArg, maxTimePerChunk, callback) {
let that = this;
let args = Array.from(arguments);
let lastArg = args.pop();
if (lastArg instanceof Function) {
callback = lastArg;
lastArg = args.pop();
} else {
callback = function() {};
}
if (Number(lastArg) === lastArg) {
maxTimePerChunk = lastArg;
lastArg = args.pop();
} else {
maxTimePerChunk = 200;
}
if (args.length === 1) {
thisArg = lastArg;
} else {
thisArg = that
}
let index = 0;
function now() {
return new Date().getTime();
}
function doChunk() {
let startTime = now();
while (index < that.length && (now() - startTime) <= maxTimePerChunk) {
// callback called with args (value, index, array)
fn.call(thisArg, that[index], index, that);
++index;
}
if (index < that.length) {
// set Timeout for async iteration
setTimeout(doChunk, 1);
} else {
callback();
}
}
doChunk();
}
}