Skip to content

Instantly share code, notes, and snippets.

@brainysmurf
Last active May 26, 2020 01:02
Show Gist options
  • Save brainysmurf/054c3e467cbbbc8c237b67e647b18968 to your computer and use it in GitHub Desktop.
Save brainysmurf/054c3e467cbbbc8c237b67e647b18968 to your computer and use it in GitHub Desktop.
How to make a timer with a context manager

Timer

This is some sample code that shows how use a design pattern to implement a timer.

To use:

  • Create the new Timer instance, indicating time
  • call .body on the instance, where the first parameter is the function to execute
  • periodically within that function, call this.check() which will raise TimeUpErr error if the duration has expired
function myFunction() {
  const timer = new Timer({seconds: 2});
 
  timer.body(function () {
    for (let x = 0; x < 2000000; x++) {
      if (x % 1000 === 0) {
        Logger.log('zzzz');
        Utilities.sleep(1000);
        this.check();
      }
    }
    Logger.log('loop done');
  });
}
class TimeUpErr extends Error {
}
class ContextManager {
enter () {
// set up state
}
error (err) {
return null; // returning null indicates we don't want to re-raise it in exit block
}
exit () {
// we
}
body (func) {
let result;
// execute the enter function
this.enter();
try {
// bind it so we can access via `this`
result = func.call(this);
} catch (err) {
// execute the error handler
// error handler can return null to indicate it should be swallowed
const swallow = this.error(err) === null;
// if error happened, call error function
// if it returns null swallow it, otherwise reraise
if (!swallow)
throw err;
} finally {
// execute the exit
this.exit();
}
return result;
}
}
class Timer extends ContextManager {
constructor ({seconds=10, minutes=0}={}) {
super();
this.milliseconds = (seconds * 1000) + (minutes * 60 * 1000);
}
enter () {
this.start = new Date();
this.timeup = false;
}
exit () {
if (this.timeup) {
Logger.log('inform user');
}
}
error (err) {
if (err instanceof TimeUpErr) {
return null; // swallow it
}
Logger.log(err.message);
}
check () {
const now = new Date();
if (now.getTime() - this.start.getTime() >= (this.milliseconds)) {
this.timeup = true;
throw new TimeUpErr('Time is up');
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment