How to override setTimeout() and setInterval() to allow dynamic adjustments

I am debugging some complex animation stuff and sometimes I need to slow down time to see what is exactly going on. Since the code is very complex, modification of the animation code is not a viable option. Therefore, I decided to modify the Date class as follows:

let ___date = Date.now();
const ___now = Date.now;
Date = new Proxy(Date, {
  construct(target, args) {
    if (args[0] === undefined) args[0] = this.adjust()
    let date = new target(...args);
    return date;
  },
  get(target, prop, receiver) {
    if (prop === 'now') {
      let date = new Date()
      date.now = () => this.adjust()
      return Reflect.get(date, prop, receiver)
    }
    return Reflect.get(target, prop, receiver)
  },    
  apply(target, thisArg, argumentList) {
    return toString.bind(new Date()).call();
  },
  adjust() {
    // ...
  }
});

This works as desired for new Data() and Date.now(). With this simple modification, I was able to move on, but later I found out that the code is not running as expected, as some parts of the code were still running with the speed that ignored my adjustment. I quickly realized that functions setTimeout() and setInterval() are those that cause my problems.

How can I override setTimeout() and setInterval() so I can adjust time dynamically, i.e. not just when the function is started, but also during ticking?

8 thoughts on “How to override setTimeout() and setInterval() to allow dynamic adjustments”

Leave a Comment