1+ // NOTE: Run this script in browser snippets as running on Node.js environment will throw `window is not defined` error.
2+
3+
4+ ( function ( ) {
5+ // Object to store registered timers
6+ const timerCallbackMap = { } ;
7+
8+
9+ // Function to generate unique ids for a particular callback
10+ function generateId ( ) {
11+ const chars = "12356ABCDEF" ;
12+ let key = "" ;
13+ for ( let i = 0 ; i < 6 ; i ++ ) {
14+ const idx = Math . floor ( Math . random ( ) * chars . length ) ;
15+ key += chars [ idx ] ;
16+ }
17+ return key ;
18+ }
19+
20+
21+ // Function to be called when browser is idle to check if any callback execution time is pass the current time
22+ function check ( ) {
23+ if ( timerCallbackMap . size === 0 ) return ;
24+
25+ for ( let timerId in timerCallbackMap ) {
26+ const now = Date . now ( ) ;
27+ if ( now > timerCallbackMap [ timerId ] . execTime ) {
28+ timerCallbackMap [ timerId ] . callback ( ) ;
29+ window . myClearTimeout ( timerId ) ;
30+ }
31+ }
32+
33+ requestIdleCallback ( check ) ;
34+ }
35+
36+
37+ // Polyfill for setTimeout
38+ window . mySetTimeout = function ( callback , delay = 0 ) {
39+ // check if arguments are of correct type
40+ if ( typeof callback !== "function" ) throw new Error ( "cb should be a function" ) ;
41+ if ( typeof delay !== "number" || delay < 0 )
42+ throw new Error ( "delay should be a positive number" ) ;
43+
44+
45+ // generate unique id for callback
46+ const timerId = generateId ( ) ;
47+
48+
49+ // store the callback and set its execution time as current epoch value + delay in milliseconds
50+ timerCallbackMap [ timerId ] = {
51+ callback,
52+ execTime : Date . now ( ) + delay
53+ } ;
54+
55+ // queue the check function to be called when browser is idle
56+ if ( Object . keys ( timerCallbackMap ) . length === 1 ) requestIdleCallback ( check ) ;
57+
58+ return timerId ;
59+ } ;
60+
61+
62+ // Polyfill for clearTimeout
63+ window . myClearTimeout = function ( timerId ) {
64+ if ( timerCallbackMap [ timerId ] ) {
65+ delete timerCallbackMap [ id ] ;
66+ }
67+ } ;
68+ } ) ( ) ;
69+
70+ const id = mySetTimeout ( ( ) => {
71+ console . log ( "Hello" ) ;
72+ } , 2000 ) ;
73+
0 commit comments