36. fake timer(setTimeout)を実装する
シェアしよう
少し工夫が必要 - accepted / - tried
setTimeout
を使えば一定時間後に実行されるタスクを設置することができる。だけどそのタスクの本当の実行時間は精確ではない。(詳しくはEvent Loopを見てください。)。
ほとんどの場合はこれが問題にならないが、テストする時などではちょっと困る。
例えば、5. leading & trailingをサポートするthrottle() を実装する では精確なタイマーが必要になる。
Event Loopの問題なく、精確なsetTimeout()
和clearTimeout()
を作ってくだい。これもFakeTimes がやっていることです。
「精確」というのは、関数の実行時間を0とし、時間は0からスタートすると、setTimeout(func1, 100)
ではfunc1が必ず時間:100に実行される。
Date.now()
の実装も入れ替える必要がある。
class FakeTimer {
install() {
// setTimeout(), clearTimeout(), and Date.now()
// are replaced
}
uninstall() {
// restore the original APIs
// setTimeout(), clearTimeout() and Date.now()
}
tick() {
// run all the schedule functions in order
}
}
あなたのコードはこんな感じでテストされる。
const fakeTimer = new FakeTimer()
fakeTimer.install()
const logs = []
const log = (arg) => {
logs.push([Date.now(), arg])
}
setTimeout(() => log('A'), 100)
// log 'A' at 100
const b = setTimeout(() => log('B'), 110)
clearTimeout(b)
// b is set but cleared
setTimeout(() => log('C'), 200)
expect(logs).toEqual([[100, 'A'], [200, 'C']])
fakeTimer.uninstall()
補足
時間に関係する関数の中ではDate.now()
だけ対応が必要、その他は無視して良い。