Last active
April 20, 2023 04:05
-
-
Save leizongmin/92526235d89ee7dec11e52bd4ec26e01 to your computer and use it in GitHub Desktop.
Use `queueMicrotask` to implement timer function
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function setTimeout(callback, delay, ...args) { | |
const id = setTimeout._nextId++; | |
const start = Date.now(); | |
function loop() { | |
queueMicrotask(() => { | |
if (!setTimeout._timers[id]) return; | |
if (Date.now() - start >= delay) { | |
delete setTimeout._timers[id]; | |
callback(...args); | |
} else { | |
loop(); | |
} | |
}); | |
} | |
setTimeout._timers[id] = [callback, ...args]; | |
loop(); | |
return id; | |
} | |
setTimeout._timers = {}; | |
setTimeout._nextId = 1; | |
function clearTimeout(id) { | |
delete setTimeout._timers[id]; | |
} | |
function setInterval(callback, interval, ...args) { | |
const id = setTimeout._nextId++; | |
let start = Date.now(); | |
function loop() { | |
queueMicrotask(() => { | |
if (!setTimeout._timers[id]) return; | |
if (Date.now() - start >= interval) { | |
start = Date.now(); | |
callback(...args); | |
loop(); | |
} else { | |
loop(); | |
} | |
}); | |
} | |
setTimeout._timers[id] = [callback, ...args]; | |
loop(); | |
return id; | |
} | |
function clearTimeout(id) { | |
delete setTimeout._timers[id]; | |
} | |
function clearInterval(id) { | |
clearTimeout(id); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
console.log(Date.now()); | |
const a = [111, 222, 333]; | |
const b = [444, 555, 666]; | |
let count = 0; | |
// timeout | |
setTimeout((...args) => console.log(Date.now(), ...args), 12345, ...a); | |
// interval | |
const id1 = setInterval( | |
(...args) => { | |
count++; | |
console.log(Date.now(), count, ...args); | |
if (count >= 5) { | |
clearInterval(id1); | |
} | |
}, | |
1000, | |
...b | |
); | |
// cancel the timer | |
const id2 = setTimeout(() => console.log("timeout"), 1000); | |
clearTimeout(id2); | |
/* | |
will output something like: | |
1681963305259 | |
1681963306260 1 444 555 666 | |
1681963307260 2 444 555 666 | |
1681963308260 3 444 555 666 | |
1681963309260 4 444 555 666 | |
1681963310260 5 444 555 666 | |
1681963317605 111 222 333 | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment