Last active
November 21, 2017 20:26
-
-
Save joeyjiron06/9c285a49042d6a266f42c0e1208909b3 to your computer and use it in GitHub Desktop.
A simple throttler utility function
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* A simple throttle utility function. Usefull for expensive methods that | |
* might be called very rapidly in succession | |
* @param {number} delay - delay in millis to throttle the function callback | |
* @param {function} fn - the callback to invoke when throttled | |
* @return {function} a method to invoke many times during a period that you would like to throttle | |
*/ | |
module.exports = function throttler(delay, fn) { | |
if (typeof delay !== 'number') { | |
throw new Error('you must pass in a number'); | |
} | |
if (typeof fn !== 'function') { | |
throw new Error('you must pass in a function'); | |
} | |
let lastCalled = 0; | |
return function throttle() { | |
const now = Date.now(); | |
const delta = now - lastCalled; | |
if (delta >= delay) { | |
lastCalled = now; | |
fn.apply(fn, arguments); | |
} | |
}; | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const chai = require('chai'); | |
const spies = require('chai-spies'); | |
const throttler = require('./Throttler'); | |
const { expect } = chai; | |
chai.use(spies); | |
describe('throttlerr', () => { | |
it('should throw an error if anything but a number is given for the first argument', () => { | |
expect(() => throttler(null)).to.throw(); | |
expect(() => throttler(undefined)).to.throw(); | |
expect(() => throttler(NaN)).to.throw(); | |
expect(() => throttler('hi')).to.throw(); | |
expect(() => throttler(function(){})).to.throw(); | |
expect(() => throttler({})).to.throw(); | |
}); | |
it('should throw an error if anything but a function is given for the second argument', () => { | |
expect(() => throttler(10, null)).to.throw(); | |
expect(() => throttler(10, undefined)).to.throw(); | |
expect(() => throttler(10, NaN)).to.throw(); | |
expect(() => throttler(10, 'hi')).to.throw(); | |
expect(() => throttler(10, 123)).to.throw(); | |
expect(() => throttler(10, {})).to.throw(); | |
}); | |
it('should call the callback at least 3 times during the throttle period', (done) => { | |
const spy = chai.spy(); | |
const throttle = throttler(50, spy); | |
const start = Date.now(); | |
let interval = setInterval(() => { | |
throttle(123, 'hi', NaN); | |
if ((Date.now() - start) >= 200) { | |
clearInterval(interval); | |
expect(spy).to.have.been.called.at.least(4); | |
expect(spy).to.have.been.called.always.with.exactly(123, 'hi', NaN); | |
done(); | |
} | |
}, 10); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment