Let's say I am using the following code to run a couple of promises in series:
let paramerterArr = ['a','b','c','d','e','f']
parameterArr.reduce(function(promise, item) {
return promise.then(function(result) {
return mySpecialFunction(item);
})
}, Promise.resolve())
The code simply calls mySpecialFunction (which returns a promise), waits for the promise to be resolved and then calls mySpecialFunction again etc. So the function is called once for every element in the array, in the correct order.
How could I make sure that there is a delay of at least 50 milliseconds between every call of mySpecialFunction(item)
?
It is important that the promises are executed in the right order and the execution time of mySpecialFunction
varies every time.
I guess a synchronous sleep would work, but I'm not planning to run this code in a separate thread, so it would cause annoying ui freezes in the browser.
I'm not sure if setTimer could somehow be used for this. I mean I can't delay the returning of a promise.
The answers are good, but they wait too long since all the answers wait regardless of whether or not the actual operation took more than 50ms already.
You can use Promise.all
for it.
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
let parameterArr = ['a','b','c','d','e','f'];
parameterArr.reduce(function(promise, item) {
return promise.then(function(result) {
return Promise.all([delay(50), myPromise(item)]);
});
}, Promise.resolve());
A really handy utility function to have around is something I call delay()
:
function delay(t, val) {
return new Promise(function(resolve) {
if (t <= 0) {
resolve(val);
} else {
setTimeout(resolve.bind(null, val), t);
}
});
}
Then, you can use it in a promise chain like this:
let paramerterArr = ['a','b','c','d','e','f']
parameterArr.reduce(function(promise, item, index) {
return promise.then(function(result) {
// no delay on first iteration
var delayT = index ? 50 : 0;
return delay(delayT, item).then(mySpecialFunction);
})
}, Promise.resolve());
You could also make a little utility function for doing the sequential iteration with optional delay:
// delayT is optional (defaults to 0)
function iterateSerialAsync(array, delayT, fn) {
if (!fn) {
fn = delayT;
delayT = 0;
}
array.reduce(function(p, item, index) {
return p.then(function() {
// no delay on first iteration
if (index === 0) delayT = 0;
return delay(delayT, item).then(fn)
});
}, Promise.resolve());
}
And, then you would use it like this:
iterateSerialAsync(paramerterArr, 50, mySpecialFunction).then(function(finalVal) {
// all done here
});
To get a delay of at least 50ms, use Promise.all
:
function delay(t) {
return new Promise(function(resolve) {
setTimeout(resolve, t);
});
}
parameterArr.reduce(function(promise, item) {
return promise.then(function() {
return Promise.all([
mySpecialFunction(item),
delay(50)
]);
});
}, Promise.resolve());
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