Last active
November 29, 2018 19:35
-
-
Save joeyjiron06/1532b20557850ea1b98f7d5f1b12bd70 to your computer and use it in GitHub Desktop.
poller.js - simple javascript poller
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
{ | |
"name": "poller", | |
"version": "1.0.0", | |
"description": "", | |
"main": "poller.js", | |
"dependencies": {}, | |
"devDependencies": { | |
"chai": "^4.1.2", | |
"mocha": "^5.1.1" | |
}, | |
"scripts": { | |
"test": "mocha *.test.js" | |
}, | |
"author": "", | |
"license": "ISC" | |
} |
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 super simple polling function. It takes in a function that should be called with a specified delay. | |
* This function returns a function that, when invoked, will cancel and pending timeouts/polling and will | |
* block all subsequent calls from firing a poll event | |
* @example | |
* this.cancelPolling = poller(poll => { | |
* fetchUserLogin() | |
* .then(data => { | |
* if (!data.hasLoggedIn) { | |
* poll(5000); | |
* } else { | |
* this.onUserLoggedIn(data); | |
* } | |
* }) | |
* .catch(err => { | |
* poll(10000); // poll longer on errors | |
* }); | |
* }); | |
* | |
* ... | |
* onCancelButtonClicked() { | |
* if (this.cancelPolling) { | |
* this.cancelPolling(); | |
* this.cancelPolling = null; | |
* } | |
* } | |
* | |
* | |
* @param {function} fn - a function that is invoked after each delay | |
* @return {function} a function that, when invoked, will cancel any pending poll | |
*/ | |
module.exports = fn => { | |
let isCancelled = false; | |
let timer = null; | |
const cancel = () => { | |
if (!isCancelled) { | |
clearTimeout(timer); | |
timer = null; | |
isCancelled = true; | |
} | |
}; | |
const pollDelayed = delayMillis => { | |
clearTimeout(timer); | |
timer = setTimeout(() => { | |
if (isCancelled) { | |
return; | |
} | |
fn(pollDelayed); | |
}, delayMillis); | |
}; | |
fn(pollDelayed); | |
return cancel; | |
}; |
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 { expect } = require("chai"); | |
const poller = require("./poller"); | |
describe("poller", () => { | |
it("should return a function", () => { | |
expect(typeof poller(() => {})).to.equal("function"); | |
}); | |
it("should poll after the specified delay", done => { | |
const start = Date.now(); | |
const delay = 100; | |
let count = 0; | |
poller(poll => { | |
if (count === 3) { | |
const duration = Date.now() - start; | |
expect(duration).to.be.greaterThan(count * delay); | |
done(); | |
return; | |
} | |
count++; | |
poll(100); | |
}); | |
}); | |
it("should cancel the polling", done => { | |
const pollDelayMillis = 100; | |
const maxCount = 5; | |
let count = 0; | |
const cancel = poller(poll => { | |
if (++count === maxCount) { | |
cancel(); | |
} | |
poll(pollDelayMillis); | |
}); | |
setTimeout(() => { | |
expect(count).to.equal(5); | |
done(); | |
}, pollDelayMillis * (maxCount + 2)); | |
}); | |
it("should poll once if cancelled immediately", done => { | |
let count = 0; | |
const cancel = poller(poll => { | |
count++; | |
poll(10); | |
}); | |
cancel(); | |
setTimeout(() => { | |
expect(count).to.equal(1); | |
done(); | |
}, 50); | |
}); | |
it("should protect against calling poll mutiple times in the callback", done => { | |
let count = 0; | |
poller(poll => { | |
if (++count === 5) { | |
return; | |
} | |
poll(10); | |
poll(10); | |
poll(10); | |
}); | |
setTimeout(() => { | |
expect(count).to.equal(5); | |
done(); | |
}, 100); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment