この解答例は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()
が経過時間を予測できることが期待されます。ただし、これらの関数が実行された時間を変更する必要性がある場合、これらの関数を呼び出す前に時間を変更する必要があります。