この解答例はChatGPTによって生成されています,正しいかは自己判断で。 皆の投稿からも解答例が見つかるかもしれませんよ。
BFE.devでのAI解答例 - JavaScript コーディング問題
36. fake timer(setTimeout)を実装する
以下がJavaScriptのコードになります。
class FakeTimer { constructor() { this.timers = new Map() this.currentTimestamp = 0 } getCurrentTimestamp() { return this.currentTimestamp } install() { const originalSetTimeout = window.setTimeout window.setTimeout = (func, delay, ...args) => { const timer = setTimeout(func, delay, ...args) this.timers.set(timer, { func, delay, created: this.currentTimestamp }) return timer } const originalClearTimeout = window.clearTimeout window.clearTimeout = (timer) => { this.timers.delete(timer) originalClearTimeout(timer) } const originalDateNow = Date.now Date.now = () => this.currentTimestamp } uninstall() { window.setTimeout = setTimeout window.clearTimeout = clearTimeout Date.now = Date.now } tick(time) { if (time === undefined) { time = Math.max(1, ...Array.from(this.timers.values()).map((timer) => (timer.created + timer.delay) - this.currentTimestamp )) } const remainingTimers = new Map() this.timers.forEach((timer, timerId) => { const elapsed = this.currentTimestamp - timer.created const remainingTime = Math.max(0, timer.delay - elapsed) if (remainingTime <= time) { timer.func() } else { remainingTimers.set(timerId, { ...timer, delay: remainingTime }) } }) this.timers = remainingTimers this.currentTimestamp += time }}
この実装では、setTimeout()
とclearTimeout()
、そしてDate.now()
を上書きしています。setTimeout()
は、実行予定の関数と経過時間を記録してタイマーIDを返します。clearTimeout()
は、タイマーIDを引数にとって、対応する登録済みのタイマーを削除します。
tick()
関数は実装済みのタイマーを調べ、経過した時間に応じて適切なタイマーを実行します。一方、まだ経過時間が残っているタイマーは、再度登録してタイマー実行を予約します。time
引数が指定されている場合、 tick()
が指定された時間まで進みます。
テストされているように、この実装によって setTimeout()
や clearTimeout()
が経過時間を予測できることが期待されます。ただし、これらの関数が実行された時間を変更する必要性がある場合、これらの関数を呼び出す前に時間を変更する必要があります。