I am trying to loop through an array of AsynWork to be done. And cant flood the system with async work done all at the time. so I am trying to do one by one with promises. My problem is that I need to go though an array of values so each async works on each value of the array. I managed to do it with this code, but it works for my specific case. Can't make it general. What would be the approach to make it reusable for other type of arrays? I have seen some solutions with array.reduce then promises but cant figure it out. Also have seen examples with Q but not using, if it can be done with simple javascript would be better.
My Code:
function doSomething(ObjIn1, ObjIn2) {
return new Promise(function(resolve, reject) {
console.log("doSomething: ObjIn1: " + ObjIn1 + " ObjIn2: " + ObjIn2);
setTimeout(function() {
console.log("doSomething Done: ObjIn1: " + ObjIn1 + " ObjIn2: " + ObjIn2);
resolve(ObjIn1, ObjIn2);
}, 500);
})
}
function LoopPromises(Function2Loop, functionOptions, Counter, Max) {
console.log("Counter: " + Counter);
if (Counter < Max) {
Function2Loop.apply(this, [functionOptions[0][Counter], functionOptions[1]]).then(function() {
Counter++;
LoopPromises(Function2Loop, functionOptions, Counter, Max);
});
}
}
LoopPromises(doSomething, [
["A1", "A2", "A3"], "ARG2TESTE"
], 0, 3)
You're overthinking this :) A function with arguments is the same as a function without arguments closing over a function with arguments so:
a(1,2,3,4);
Is the same as
(() => a(1,2,3,4))();
Except perhaps negligibly slower. I'm assuming you need to queue the work for an arbitrary amount of promises. If you need to do it for a fixed number - you can just then between them. Let's see how we can do this:
// runs fn on the array elements in sequence, but
function sequence(fns) { // fns - functions returning promises
return fns.reduce((prev, nextFn) => { // 'fold' the array
return prev.then(nextFn); // after the previous is done, execute the next
}, Promise.resolve()); // start with an empty promise
}
Make sure you understand reduce first. For convenience - let's see an example without it:
function sequence(fns) { // fns - functions returning promises
var queue = Promise.resolve();
fns.forEach(fn => queue = queue.then(fn));
return queue;
}
We're iterating through our array of work (functions) and executing them one after the other where we execute the next after the promise the previous returned resolved.
Where the values wait for each other based on the promise resolving (via then). This would let you do:
sequence([
() => new Promise(r => setTimeout(r, 500));
() => console.log("I only run after the previous work completed");
]);
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