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