I am trying to make a function that delays the execution of asynchronous functions by X ms.
For the purposes of this demonstration, the followi
Here's your problem:
setTimeout(anUrl => {
return new Promise( fulfil => {
fulfil(asyncMock(anUrl));
});
}, throttleMs, url);
What you're doing here is you return a promise from the setTimeout callback. The return value of functions run by setTimeout are ignored so no one will get that value.
Because throttleAsync
returns the result of calling promise.then
, and the then
callback doesn't return anything. This makes the promise created by then
resolve with the value undefined
.
You probably meant to have it return the new promise you're creating, but you're not doing that until the setTimeout
callback. You want to do it prior (but there's more, keep reading):
let throttleAsync = function(url) {
return promise.then(() => {
return new Promise( fulfil => {
setTimeout(anUrl => {
fulfil(asyncMock(anUrl));
}, throttleMs, url);
});
});
};
There's also no reason to pass the URL through setTimeout
like that, so:
let throttleAsync = function(url) {
return promise.then(() => {
return new Promise( fulfil => {
setTimeout(() => {
fulfil(asyncMock(url));
}, throttleMs);
});
});
};
Originally I though the promise
there was unnecessary, but you've clarified that you want to ensure that repeated calls are "spaced out" by throttleMs
. To do that, we'd use the above, but update promise
:
let throttleAsync = function(url) {
return promise = promise.then(() => {
// ^^^^^^^^^
return new Promise( fulfil => {
setTimeout(() => {
fulfil(asyncMock(url));
}, throttleMs);
});
});
};
This way, the next call to asyncThrottle
will wait until the previous one has fired before starting the next.
Live Example:
const throttleMs = 1000;
const asyncMock = url => url;
let promise = Promise.resolve();
let throttleAsync = function(url) {
return promise = promise.then(() => {
// ^^^^^^^^^
return new Promise( fulfil => {
setTimeout(() => {
fulfil(asyncMock(url));
}, throttleMs);
});
});
};
console.log('running');
throttleAsync('http://www.bananas.pt')
.then(console.log)
.catch(console.error);
throttleAsync('http://www.fruits.es')
.then(console.log)
.catch(console.error);
throttleAsync('http://www.veggies.com')
.then(console.log)
.catch(console.error);