(ngZone: NgZone)
| 121 | } |
| 122 | |
| 123 | private scheduleTimer(ngZone: NgZone) { |
| 124 | const callback = () => { |
| 125 | this.clearTimeout(); |
| 126 | |
| 127 | this.executingCallbacks = true; |
| 128 | |
| 129 | // Clone the current state of the queue, since it might be altered |
| 130 | // as we invoke callbacks. |
| 131 | const current = [...this.current]; |
| 132 | |
| 133 | // Invoke callbacks that were scheduled to run before the current time. |
| 134 | const now = Date.now(); |
| 135 | for (let i = 0; i < current.length; i += 2) { |
| 136 | const invokeAt = current[i] as number; |
| 137 | const callback = current[i + 1] as VoidFunction; |
| 138 | if (invokeAt <= now) { |
| 139 | callback(); |
| 140 | } else { |
| 141 | // We've reached a timer that should not be invoked yet. |
| 142 | break; |
| 143 | } |
| 144 | } |
| 145 | // The state of the queue might've changed after callbacks invocation, |
| 146 | // run the cleanup logic based on the *current* state of the queue. |
| 147 | let lastCallbackIndex = -1; |
| 148 | for (let i = 0; i < this.current.length; i += 2) { |
| 149 | const invokeAt = this.current[i] as number; |
| 150 | if (invokeAt <= now) { |
| 151 | // Add +1 to account for a callback function that |
| 152 | // goes after the timestamp in events array. |
| 153 | lastCallbackIndex = i + 1; |
| 154 | } else { |
| 155 | // We've reached a timer that should not be invoked yet. |
| 156 | break; |
| 157 | } |
| 158 | } |
| 159 | if (lastCallbackIndex >= 0) { |
| 160 | arraySplice(this.current, 0, lastCallbackIndex + 1); |
| 161 | } |
| 162 | |
| 163 | this.executingCallbacks = false; |
| 164 | |
| 165 | // If there are any callbacks added during an invocation |
| 166 | // of the current ones - move them over to the "current" |
| 167 | // queue. |
| 168 | if (this.deferred.length > 0) { |
| 169 | for (let i = 0; i < this.deferred.length; i += 2) { |
| 170 | const invokeAt = this.deferred[i] as number; |
| 171 | const callback = this.deferred[i + 1] as VoidFunction; |
| 172 | this.addToQueue(this.current, invokeAt, callback); |
| 173 | } |
| 174 | this.deferred.length = 0; |
| 175 | } |
| 176 | this.scheduleTimer(ngZone); |
| 177 | }; |
| 178 | |
| 179 | // Avoid running timer callbacks more than once per |
| 180 | // average frame duration. This is needed for better |
no test coverage detected