Might I suggest RxJS?
RxJS is not specifically for throttling, but it can definitely do that and so much more. RxJS is a library for doing reactive functional programming, which makes handling complex asynchronous interactions like this much easier.
Example:
class Throttler {
/**
* A Subject behaves as an event stream. You pump values
* into the stream and each value gets pumped through
* the pipeline below.
*/
request$ = new Subject();
constructor() {
this.request$
/* Scan keeps track of what request number we're on. */
.scan((acc, url, index) => {
const delay = (index < 5)
? (index === 0) ? 0 : 1
: 1000;
return {
url: url,
delay: delay
};
}, {})
.flatMap(({ url, delay }) => {
/* Timer will delay by the given `delay`
and then make the request. */
return Observable.timer(delay)
.flatMap(() =>
Observable.fromPromise(
axios.get(url, { responseType: 'json' })
)
);
})
/* subscribe() receives responses as they stream through. */
.subscribe((data) => {
console.log(data);
});
}
makeRequest(url) {
this.request$.next(url); // Pumps the URL into the stream.
}
}
const throttler = new Throttler();
/* Will wait 1 ms between calls */
throttler.makeRequest('localhost/whatever');
throttler.makeRequest('localhost/whatever');
throttler.makeRequest('localhost/whatever');
throttler.makeRequest('localhost/whatever');
throttler.makeRequest('localhost/whatever');
/* Will wait 3600 ms between calls hereafter */
throttler.makeRequest('localhost/whatever');
throttler.makeRequest('localhost/whatever');
throttler.makeRequest('localhost/whatever');