| OLD | NEW |
| (Empty) |
| 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} steps array of functions to invoke in sequence. | |
| 12 * @param {Object} logger logger. | |
| 13 * @param {function} callback callback to invoke on success. | |
| 14 * @param {function} failureCallback callback to invoke on failure. | |
| 15 * @constructor | |
| 16 */ | |
| 17 function FunctionSequence(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.onError = this.onError_.bind(this); | |
| 28 this.finish = this.finish_.bind(this); | |
| 29 this.nextStep = this.nextStep_.bind(this); | |
| 30 this.apply = this.apply_.bind(this); | |
| 31 } | |
| 32 | |
| 33 /** | |
| 34 * Sets new callback | |
| 35 * | |
| 36 * @param {function} callback new callback to call on succeed. | |
| 37 */ | |
| 38 FunctionSequence.prototype.setCallback = function(callback) { | |
| 39 this.callback_ = callback; | |
| 40 }; | |
| 41 | |
| 42 /** | |
| 43 * Sets new error callback | |
| 44 * | |
| 45 * @param {function} failureCallback new callback to call on failure. | |
| 46 */ | |
| 47 FunctionSequence.prototype.setFailureCallback = function(failureCallback) { | |
| 48 this.failureCallback_ = failureCallback; | |
| 49 }; | |
| 50 | |
| 51 | |
| 52 /** | |
| 53 * Error handling function, which traces current error step, stops sequence | |
| 54 * advancing and fires error callback. | |
| 55 * | |
| 56 * @param {string} err Error message. | |
| 57 * @private | |
| 58 */ | |
| 59 FunctionSequence.prototype.onError_ = function(err) { | |
| 60 this.logger.vlog('Failed step: ' + this.steps_[this.currentStepIdx_].name + | |
| 61 ': ' + err); | |
| 62 if (!this.failed_) { | |
| 63 this.failed_ = true; | |
| 64 this.failureCallback_(err); | |
| 65 } | |
| 66 }; | |
| 67 | |
| 68 /** | |
| 69 * Finishes sequence processing and jumps to the last step. | |
| 70 * This method should not be used externally. In external | |
| 71 * cases should be used finish function, which is defined in closure and thus | |
| 72 * has access to internal variables of functionsequence. | |
| 73 * @private | |
| 74 */ | |
| 75 FunctionSequence.prototype.finish_ = function() { | |
| 76 if (!this.failed_ && this.currentStepIdx_ < this.steps_.length) { | |
| 77 this.currentStepIdx_ = this.steps_.length; | |
| 78 this.callback_(); | |
| 79 } | |
| 80 }; | |
| 81 | |
| 82 /** | |
| 83 * Advances to next step. | |
| 84 * This method should not be used externally. In external | |
| 85 * cases should be used nextStep function, which is defined in closure and thus | |
| 86 * has access to internal variables of functionsequence. | |
| 87 * @private | |
| 88 * @param {...} var_args // TODO(JSDOC). | |
| 89 */ | |
| 90 FunctionSequence.prototype.nextStep_ = function(var_args) { | |
| 91 if (this.failed_) { | |
| 92 return; | |
| 93 } | |
| 94 | |
| 95 if (++this.currentStepIdx_ >= this.steps_.length) { | |
| 96 this.logger.vlog('Sequence ended'); | |
| 97 this.callback_.apply(this, arguments); | |
| 98 } else { | |
| 99 this.logger.vlog('Attempting to start step [' + | |
| 100 this.steps_[this.currentStepIdx_].name + | |
| 101 ']'); | |
| 102 try { | |
| 103 this.steps_[this.currentStepIdx_].apply(this, arguments); | |
| 104 } catch (e) { | |
| 105 this.onError(e.toString()); | |
| 106 } | |
| 107 } | |
| 108 }; | |
| 109 | |
| 110 /** | |
| 111 * This function should be called only once on start, so start sequence pipeline | |
| 112 * @param {...} var_args // TODO(JSDOC). | |
| 113 */ | |
| 114 FunctionSequence.prototype.start = function(var_args) { | |
| 115 if (this.started) { | |
| 116 throw new Error('"Start" method of FunctionSequence was called twice'); | |
| 117 } | |
| 118 | |
| 119 this.logger.log('Starting sequence with ' + arguments.length + ' arguments'); | |
| 120 | |
| 121 this.started = true; | |
| 122 this.nextStep.apply(this, arguments); | |
| 123 }; | |
| 124 | |
| 125 /** | |
| 126 * Add Function object mimics to FunctionSequence | |
| 127 * @private | |
| 128 * @param {*} obj // TODO(JSDOC). | |
| 129 * @param {Array.*} args // TODO(JSDOC). | |
| 130 */ | |
| 131 FunctionSequence.prototype.apply_ = function(obj, args) { | |
| 132 this.start.apply(this, args); | |
| 133 }; | |
| OLD | NEW |