Iterate[.md]
iterate
is a utility function that allows for execution of asynchronous code in the iteratee, waiting for each iteration to finish before moving on. This was inspired by the plugin interface of the Node.js server framework Hapi. Hapi plugins historically had the following structure:
function myPlugin(server, options, next) {
doSomethingAsynchronous(() => {
next();
});
}
The next plugin in the queue won't be registered until the preceding plugin calls next()
. My goal was to implement a similar functionality for arrays, like forEach
, but with an extra next
parameter passed to the iteratee.
Implementation
function iterate(arr, iteratee, fn) {
(function step(i) {
if (i in arr) {
iteratee(arr[i], i, arr, () => {
step(i + 1);
});
} else {
fn();
}
})(0);
}
Example:
const arr = ['foo', 'bar', 'baz'];
console.log('start');
iterate(arr, (item, i, arr, next) => {
setTimeout(() => {
console.log(item);
next();
}, 1000);
}, () => {
console.log('finish');
});
> 0s (+0s) "start"
> 1s (+1s) "foo"
> 2s (+1s) "bar"
> 3s (+1s) "baz"
> 3s (+0s) "finish"
Update 2020
Of course nowadays with the current Ecmascript spec, you could just pair for...of
and async
functions to accomplish the same thing:
async () => {
for (const item of items) {
await doSomethingAsynchronous(item);
}
};
Comments