Say I have an array and I want to perform an async-function on each element of the array.
let a = [x1, x2, x3]
// I want to
await a.forEach(async (x) => {...
I've been using this function for a while, in case if a dedicated library is not desired:
// usage:
// array.asyncEach(function(item, resume) {
// do something...
// console.log(item);
// resume(); // call `resume()` to resume the cycle
// }
//
// unless resume() is called, loop doesn't proceed to the next item
Array.prototype.asyncEach = function(iterator) {
var list = this,
n = list.length,
i = -1,
calls = 0,
looping = false;
var iterate = function() {
calls -= 1;
i += 1;
if (i === n) return;
iterator(list[i], resume);
};
var loop = function() {
if (looping) return;
looping = true;
while (calls > 0) iterate();
looping = false;
};
var resume = function() {
calls += 1;
if (typeof setTimeout === 'undefined') loop();
else setTimeout(iterate, 1);
};
resume();
};
Perform any async tasks inside the function, and call resume()
when you are done.
I don't remember where did I get this function from.
I have used a library called async. There a function called eachSeries
. It takes an array, an async function, and a callback. The function is called on each item for the array.
This question can open a rabbit hole of complexity. You will need to be careful that your async function doesn't make an asynchronous call. The library provides a callback that can be useful in this case.
function asyncFunction(val, callback) {
return (function() {
//do stuff
callback();
})();
}
The callback will initiate the a call on the next item in the array.
Is there any specific event on which these function will be called ?
if yes can be achieved through **closure** in javascript.
right now your function will be called with last value in array when you invoke it
Like this?
for (let x of a) {
await fn(x);
}
Or if you really dislike creating a separate fn
:
for (let x of a) {
await (async v => {
...
})(x);
}
You could even add it to Array.prototype
:
Array.prototype.resolveSeries = async function(fn) {
for (let x of this) {
await fn(x);
}
}
// Usage:
await a.resolveSeries(fn);
// Or:
await a.resolveSeries(async x => {
...
});