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 100const b = setTimeout(() => log('B'), 110)clearTimeout(b)// b is set but clearedsetTimeout(() => log('C'), 200)expect(logs).toEqual([[100, 'A'], [200, 'C']])fakeTimer.uninstall()
補足
時間に関係する関数の中ではDate.now()
だけ対応が必要、その他は無視して良い。