OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 'use strict'; | 5 'use strict'; |
6 | 6 |
7 /** | 7 /** |
8 * Namespace for async utility functions. | 8 * Namespace for async utility functions. |
9 */ | 9 */ |
10 var AsyncUtil = {}; | 10 var AsyncUtil = {}; |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 /** | 130 /** |
131 * Finishes the passed task and continues executing enqueued closures. | 131 * Finishes the passed task and continues executing enqueued closures. |
132 * | 132 * |
133 * @param {Object} task Task object. | 133 * @param {Object} task Task object. |
134 * @private | 134 * @private |
135 */ | 135 */ |
136 AsyncUtil.Group.prototype.finish_ = function(task) { | 136 AsyncUtil.Group.prototype.finish_ = function(task) { |
137 this.finishedTasks_[task.name] = task; | 137 this.finishedTasks_[task.name] = task; |
138 this.continue_(); | 138 this.continue_(); |
139 }; | 139 }; |
| 140 |
| 141 /** |
| 142 * Aggregates consecutive calls and executes the closure only once instead of |
| 143 * several times. The first call is always called immediately, and the next |
| 144 * consecutive ones are aggregated and the closure is called only once once |
| 145 * |delay| amount of time passes after the last call to run(). |
| 146 * |
| 147 * @param {function()} closure Closure to be aggregated. |
| 148 * @param {number=} opt_delay Minimum aggregation time in milliseconds. Default |
| 149 * is 50 milliseconds. |
| 150 * @constructor |
| 151 */ |
| 152 AsyncUtil.Aggregation = function(closure, opt_delay) { |
| 153 /** |
| 154 * @type {number} |
| 155 * @private |
| 156 */ |
| 157 this.delay_ = opt_delay || 50; |
| 158 |
| 159 /** |
| 160 * @type {function()} |
| 161 * @private |
| 162 */ |
| 163 this.closure_ = closure; |
| 164 |
| 165 /** |
| 166 * @type {number?} |
| 167 * @private |
| 168 */ |
| 169 this.scheduledRunsTimer_ = null; |
| 170 |
| 171 /** |
| 172 * @type {number} |
| 173 * @private |
| 174 */ |
| 175 this.lastRunTime_ = 0; |
| 176 }; |
| 177 |
| 178 /** |
| 179 * Runs a closure. Skips consecutive calls. The first call is called |
| 180 * immediately. |
| 181 */ |
| 182 AsyncUtil.Aggregation.prototype.run = function() { |
| 183 // If recently called, then schedule the consecutive call with a delay. |
| 184 if (Date.now() - this.lastRunTime_ < this.delay_) { |
| 185 this.cancelScheduledRuns_(); |
| 186 this.scheduledRunsTimer_ = setTimeout(this.runImmediately_.bind(this), |
| 187 this.delay_ + 1); |
| 188 this.lastRunTime_ = Date.now(); |
| 189 return; |
| 190 } |
| 191 |
| 192 // Otherwise, run immediately. |
| 193 this.runImmediately_(); |
| 194 }; |
| 195 |
| 196 /** |
| 197 * Calls the schedule immediately and cancels any scheduled calls. |
| 198 * @private |
| 199 */ |
| 200 AsyncUtil.Aggregation.prototype.runImmediately_ = function() { |
| 201 this.cancelScheduledRuns_(); |
| 202 this.closure_(); |
| 203 this.lastRunTime_ = Date.now(); |
| 204 }; |
| 205 |
| 206 /** |
| 207 * Cancels all scheduled runs (if any). |
| 208 * @private |
| 209 */ |
| 210 AsyncUtil.Aggregation.prototype.cancelScheduledRuns_ = function() { |
| 211 if (this.scheduledRunsTimer_) { |
| 212 clearTimeout(this.scheduledRunsTimer_); |
| 213 this.scheduledRunsTimer_ = null; |
| 214 } |
| 215 }; |
OLD | NEW |