| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| /** |
| * @constructor |
| * @class FunctionSequence to invoke steps in sequence |
| * |
| * @param steps array of functions to invoke in parallel |
| * @param callback callback to invoke on success |
| * @param failureCallback callback to invoke on failure |
| */ |
| function FunctionParallel(name, steps, logger, callback, failureCallback) { |
| // Private variables hidden in closure |
| this.currentStepIdx_ = -1; |
| this.failed_ = false; |
| this.steps_ = steps; |
| this.callback_ = callback; |
| this.failureCallback_ = failureCallback; |
| this.logger = logger; |
| this.name = name; |
| |
| this.remaining = this.steps_.length; |
| |
| this.nextStep = this.nextStep_.bind(this); |
| this.onError = this.onError_.bind(this); |
| this.apply = this.start.bind(this); |
| } |
| |
| |
| /** |
| * Error handling function, which fires error callback. |
| * |
| * @param err error message |
| */ |
| FunctionParallel.prototype.onError_ = function(err) { |
| if (!this.failed_) { |
| this.failed_ = true; |
| this.failureCallback_(err); |
| } |
| }; |
| |
| /** |
| * Advances to next step. This method should not be used externally. In external |
| * cases should be used nextStep function, which is defined in closure and thus |
| * has access to internal variables of functionsequence. |
| */ |
| FunctionParallel.prototype.nextStep_ = function() { |
| if (--this.remaining == 0 && !this.failed_) { |
| this.callback_(); |
| } |
| }; |
| |
| /** |
| * This function should be called only once on start, so start all the children |
| * at once |
| */ |
| FunctionParallel.prototype.start = function(var_args) { |
| this.logger.vlog('Starting [' + this.steps_.length + '] parallel tasks with ' |
| + arguments.length + ' argument(s)'); |
| if (this.logger.verbose) { |
| for (var j = 0; j < arguments.length; j++) { |
| this.logger.vlog(arguments[j]); |
| } |
| } |
| for (var i=0; i < this.steps_.length; i++) { |
| this.logger.vlog('Attempting to start step [' + this.steps_[i].name + ']'); |
| try { |
| this.steps_[i].apply(this, arguments); |
| } catch(e) { |
| this.onError(e.toString()); |
| } |
| } |
| }; |