Skip to content

Instantly share code, notes, and snippets.

@softwarespot
Last active July 17, 2017 17:41
Show Gist options
  • Save softwarespot/be3f9bdc678e7ad2949ab6f90e031af7 to your computer and use it in GitHub Desktop.
Save softwarespot/be3f9bdc678e7ad2949ab6f90e031af7 to your computer and use it in GitHub Desktop.
console.clear();
var intervalIds = {
nextId: 1,
};
/**
* Invoke a function callback on an interval delay. This is better than setInterval, as it...
* 1. Waits for the function to complete before starting the next interval
* 2. Waits for the optional returned Promise to resolve before starting the next interval
*
* @param {Function} fn A callback function to be executed every delay milliseconds.
* If a Promise is returned from the callback function, then wait for the Promise to resolve
* @param {number} delay Interval delay in milliseconds. See
* {@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout|setTimeout}
* for more details about the delay value
* @returns {number} The returned timer id is a non-zero value which identifies the timer created
* by setIntervalAsync; this value can be passed to clearIntervalAsync to clear the interval
*/
function setIntervalAsync(fn, delay) {
var timerId = arguments[2];
if (timerId === undefined) {
timerId = intervalIds.nextId;
intervalIds.nextId += 1;
}
new Promise(function (resolve) {
resolve(fn());
})
.then(function () {
if (intervalIds[timerId] !== 0) {
intervalIds[timerId] = setTimeout(function () {
setIntervalAsync(fn, delay, timerId);
}, delay);
}
})
.catch(function (err) {
// Stop the interval on fatal error
console.error('setIntervalAsync::', err);
});
return timerId;
}
/**
* Clear the timer interval created by setIntervalAsync
*
* @param {number} timerId Timer id to clear
* @returns {void}
*/
function clearIntervalAsync(timerId) {
clearTimeout(intervalIds[timerId]);
intervalIds[timerId] = 0;
}
// Example(s)
setIntervalAsync(function () {
console.log('Interval:', Date.now());
// Delay the resolution of the Promise
return new Promise(function (resolve) {
setTimeout(resolve, 1000);
});
}, 0);
// Shows how to cancel the interval
var id = 0;
var timerId = setIntervalAsync(function () {
console.log('Id:', id);
id += 1;
}, 0);
// Clear after 20ms
setTimeout(function () {
clearIntervalAsync(timerId);
}, 20);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment