Home | History | Annotate | Download | only in metadata
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 'use strict';
      6 
      7 /**
      8  * @class FunctionSequence to invoke steps in sequence
      9  *
     10  * @param {string} name  // TODO(JSDOC).
     11  * @param {Array.<function>} steps Array of functions to invoke in parallel.
     12  * @param {Object} logger  // TODO(JSDOC).
     13  * @param {function()} callback Callback to invoke on success.
     14  * @param {function(string)} failureCallback Callback to invoke on failure.
     15  * @constructor
     16  */
     17 function FunctionParallel(name, steps, logger, callback, failureCallback) {
     18   // Private variables hidden in closure
     19   this.currentStepIdx_ = -1;
     20   this.failed_ = false;
     21   this.steps_ = steps;
     22   this.callback_ = callback;
     23   this.failureCallback_ = failureCallback;
     24   this.logger = logger;
     25   this.name = name;
     26 
     27   this.remaining = this.steps_.length;
     28 
     29   this.nextStep = this.nextStep_.bind(this);
     30   this.onError = this.onError_.bind(this);
     31   this.apply = this.start.bind(this);
     32 }
     33 
     34 
     35 /**
     36  * Error handling function, which fires error callback.
     37  *
     38  * @param {string} err Error message.
     39  * @private
     40  */
     41 FunctionParallel.prototype.onError_ = function(err) {
     42   if (!this.failed_) {
     43     this.failed_ = true;
     44     this.failureCallback_(err);
     45   }
     46 };
     47 
     48 /**
     49  * Advances to next step. This method should not be used externally. In external
     50  * cases should be used nextStep function, which is defined in closure and thus
     51  * has access to internal variables of functionsequence.
     52  *
     53  * @private
     54  */
     55 FunctionParallel.prototype.nextStep_ = function() {
     56   if (--this.remaining == 0 && !this.failed_) {
     57     this.callback_();
     58   }
     59 };
     60 
     61 /**
     62  * This function should be called only once on start, so start all the children
     63  * at once
     64  * @param {...} var_args  // TODO(JSDOC).
     65  */
     66 FunctionParallel.prototype.start = function(var_args) {
     67   this.logger.vlog('Starting [' + this.steps_.length + '] parallel tasks ' +
     68                    'with ' + arguments.length + ' argument(s)');
     69   if (this.logger.verbose) {
     70     for (var j = 0; j < arguments.length; j++) {
     71       this.logger.vlog(arguments[j]);
     72     }
     73   }
     74   for (var i = 0; i < this.steps_.length; i++) {
     75     this.logger.vlog('Attempting to start step [' + this.steps_[i].name + ']');
     76     try {
     77       this.steps_[i].apply(this, arguments);
     78     } catch (e) {
     79       this.onError(e.toString());
     80     }
     81   }
     82 };
     83