Skip to content

Instantly share code, notes, and snippets.

@zach2825
Last active February 14, 2020 21:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zach2825/1b050d1e48a6e6d7c2fc2bd773600f3f to your computer and use it in GitHub Desktop.
Save zach2825/1b050d1e48a6e6d7c2fc2bd773600f3f to your computer and use it in GitHub Desktop.
JS sleep
import {randomString} from './string';
export const sleeper = (ms, {message = undefined, debug = false} = {}) => {
debug && console.log("sleeper initialized");
const hash = randomString();
const registry = {valid: true, tickCount: 0, timers: []};
let timer = null;
const tickCount = () => {
const {
tickCount = 0,
} = registry;
return tickCount;
};
const toObject = () => ({
hash,
ms,
message,
timer,
registry,
valid: registry.valid,
tickCount: tickCount(),
});
return {
id: hash,
valid: registry.valid,
timer,
tickCount,
cancel_timer: () => {
debug && console.log(`canceling.${timer}`);
clearTimeout(timer);
timer = null;
registry.valid = false;
},
tick: () => {
const new_count = tickCount() + 1;
return new Promise(resolve => {
debug && console.log(`starting.tick.${timer}`);
timer = setTimeout(() => {
debug && console.log(`resolving.tick.${timer}`);
resolve({message, ...toObject()});
registry.tickCount = new_count;
}, ms);
registry.timer = timer;
registry.timers.push(timer);
});
},
toObject,
};
};
function LooperConstructor() {
// Defaults
this.timer = null;
this.tick = {valid: true};
this.milliseconds = 5000;
this.debug = false;
this.loopCancel = () => {
this.timer && this.timer.cancel_timer();
this.tick = {valid: false};
};
this.loopStart = async ({loop_tick_callback, milliseconds = this.milliseconds, debug = this.debug}) => {
debug && console.log('loopStart.called', {loop_tick_callback, milliseconds, debug});
this.timer = sleeper(milliseconds, {identifier: 'looper@loop-start', debug});
this.tick = {valid: true};
while (this.tick.valid) {
// Await here as a workaround to sleep in js for a new seconds.
// use this to avoid using recursion
this.tick = await this.timer.tick();
debug && console.log('loopStart.tick.done', this.tick, this.tick.valid ? 'is valid' : 'is not valid');
// only show the loading state on the first loop iteration.
await loop_tick_callback();
}
}
}
export const looper = new LooperConstructor();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment