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
The following shows an example of how you might achieve a promise that doesn't block but waits for a designated time period:
function timedPromise(ms, payload) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve(payload);
}, ms);
})
}
var time = Date.now();
timedPromise(1000)
.then(function() {
console.log(time - Date.now());
return timedPromise(2000);
}).then(function() {
console.log(time - Date.now());
return timedPromise(3000);
});
So, depending on exactly what you want, you should be able to do something like this:
let paramerterArr = ['a','b','c','d','e','f']
parameterArr.reduce(function(promise, item) {
return promise.then(function(result) {
return mySpecialFunction(item);
}).then(function(specialResult) {
return timedPromise(50, specialResult);
});
}, Promise.resolve())
Here is my complete solution for delayed promise sequences:
function timeout_sequence_promise(promises = [], timeout = 200) {
//fake promise used as buffer between promises from params
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
//we need to create array of all promises with delayed buffers
let delayed_promises = [];
let total = promises.length;
let current = 0;
//every odd promise will be buffer
while (current < total) {
delayed_promises.push(promises[current]);
delayed_promises.push(delay(timeout));
current++;
}
return Promise.all(delayed_promises).then((result) => {
//we need to filter results from empty odd promises
return result.filter((item, index) => (index+2)%2 === 0);
});
}
It's receive array of promises and timeout delay in ms between them, as parameters.
Hope, it will help you!
since this seems to be a requirement of mySpecialFunction
I'd implement it there. So that the function delays itself if it is called less than 50ms after the last call
const delayBetweenCalls = (delay, fn) => {
let lastCall = NaN;
return function(/*...arguments*/){
//this and arguments are both forwarded to fn
return new Promise(resolve => {
let poll = () => {
let delta = Date.now() - lastCall;
if(delta < delay){
setTimeout(poll, delta - delay);
}else{
lastCall = Date.now();
resolve( fn.apply(this, arguments) );
}
}
poll();
})
}
}
then:
const mySpecialFunction = delayBetweenCalls(50, function(some, ...args){
return someValueOrPromise;
});
//and your loop stays the same:
parameterArr.reduce(function(promise, item) {
return promise.then(function(result) {
return mySpecialFunction(item);
})
}, Promise.resolve())
so it doesn't matter where/how mySpecialFunction
is called, there will always be a delay of at least 50ms before it runs the code inside the passed callback.
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());
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());
Here you go: https://jsbin.com/suvasox/edit?html,js,console
let paramerterArr = ['a','b','c','d','e','f']
paramerterArr.reduce((p, val) => {
return p.then(() => {
return new Promise((res) => {
setTimeout(() => { res(mySpecialFunction(val)); }, 1000);
});
});
}, Promise.resolve());
p has to be the result of the p.then(). Only that way you chain the promises.
Notice, I changed it to 1000ms delay just for emphasis.