initializer.js
2.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/**
* 依赖模块
*/
var debug = require('debug')('bootable');
/**
* 创建一个初始化实例
*
* @constructor
* @api public
*/
function Initializer() {
this._phases = [];
}
/**
* 运行所有的启动项
*
* 在运行初始化方法时, 所有的启动项将会按照注册顺序执行, 当所有启动项执行完毕
* 回调用方法才会被执行
*
* @param {Function} cb
* @param {Object} [thisArg]
* @api public
*/
Initializer.prototype.run = function (cb, thisArg) {
var phases = this._phases
, idx = 0;
function next(err) {
if (err) { return cb(err); }
var phase = phases[idx++];
// 所有启动项执行完毕
if (!phase) { return cb(); }
try {
if (typeof phase == 'object') {
debug('%s', phase.constructor ? phase.constructor.name + '#boot' : 'anonymous#boot');
phase.boot(next);
} else {
debug('%s', phase.name || 'anonymous');
var arity = phase.length;
if (arity == 1) {
phase.call(thisArg, next);
} else {
phase.call(thisArg);
next();
}
}
} catch (ex) {
next(ex);
}
}
next();
};
/**
* 注册一个启动项
*
* 一个启动项可以是同步也可以是异步的. 同步启动项如下面的片段
*
* function myPhase() {
* // perform initialization
* }
*
* 异步启动项像下面这样定义
*
* function myAsyncPhase(done) {
* // perform initialization
* done(); // or done(err);
* }
*
* 启动项也可以是一个有boot function的对象,在这样的例子中,对象上的boot function会在启动序列
* 执行的时候被调用。这种方式通常被应用在持久链接。例如数据库或是消息队列。
*
* @param {Function|Object} fn
* @returns {Initializer} `this`, for a fluent interface.
* @api public
*/
Initializer.prototype.phase = function (fn) {
this._phases.push(fn);
return this;
};
/**
* 曝露初始化对象
*/
module.exports = Initializer;