arepl
Version:
real-time python scratchpad
99 lines (87 loc) • 3.11 kB
text/typescript
/**
* class for limiting the rate of function calls.
* Thanks to Pat Migliaccio.
* see https://medium.com/@pat_migliaccio/rate-limiting-throttling-consecutive-function-calls-with-queues-4c9de7106acc
* @example let l = new limit(); let logMessageLimited = l.throttleAndQueue(msg => { console.log(msg); }, 500);
*/
export class Limit{
public callQueue = []
public lastCall
public interval: NodeJS.Timer
/**
* Returns a version of your function that can be called at most every W milliseconds, where W is wait.
* Calls to your func that happen more often than W get queued up to be called every W ms
* @param fn
* @param wait
*/
throttleAndQueue(fn: Function, wait: number){
let isCalled = false;
const self = this;
const caller = function(){
if(self.callQueue.length && !isCalled){
isCalled = true;
self.callQueue.shift().call();
setTimeout(function(){
isCalled = false;
caller();
}, wait);
}
};
return function(...args){
self.callQueue.push(fn.bind(this, ...args));
caller();
};
}
/**
* Returns a version of your function that can be called at most every W milliseconds, where W is wait.
* for calls that happen more often than W the last call will be the one called
* @param fn
* @param wait
*/
throttledUpdate(fn: Function, wait: number){
const self = this;
function caller(){
// if no timer is set then we can accept a call
if(!self.interval){
self.lastCall.call()
// check every W ms for updates
self.interval = setInterval(() => {
if(self.lastCall){
self.lastCall.call()
self.lastCall = null
}
else{
// no update, we can stop checking
clearInterval(self.interval)
self.interval = null
}
}, wait)
}
}
return function(...args){
self.lastCall = fn.bind(this, ...args);
caller()
}
}
}
/**
* limits your function to be called at most every W milliseconds, where W is wait.
* Calls over W get dropped.
* Thanks to Pat Migliaccio.
* see https://medium.com/@pat_migliaccio/rate-limiting-throttling-consecutive-function-calls-with-queues-4c9de7106acc
* @param fn
* @param wait
* @example let throttledFunc = throttle(myFunc,500);
*/
export function throttle(fn: Function, wait: number){
let isCalled = false;
return function(...args){
if(!isCalled){
fn(...args);
isCalled = true;
setTimeout(function(){
isCalled = false;
}, wait)
}
};
}