query-chainer.js
3.12 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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
var Utils = require("./utils")
module.exports = (function() {
var QueryChainer = function(emitters) {
var self = this
this.finishedEmits = 0
this.emitters = []
this.serials = []
this.fails = []
this.finished = false
this.wasRunning = false
this.eventEmitter = null
emitters = emitters || []
emitters.forEach(function(emitter) { self.add(emitter) })
}
Utils.addEventEmitter(QueryChainer)
QueryChainer.prototype.add = function(emitterOrKlass, method, params, options) {
if(!!method) {
this.serials.push({ klass: emitterOrKlass, method: method, params: params, options: options })
} else {
observeEmitter.call(this, emitterOrKlass)
this.emitters.push(emitterOrKlass)
}
return this
}
QueryChainer.prototype.run = function() {
var self = this
this.eventEmitter = new Utils.CustomEventEmitter(function() {
self.wasRunning = true
finish.call(self)
})
return this.eventEmitter.run()
}
QueryChainer.prototype.runSerially = function(options) {
var self = this
options = Utils._.extend({
skipOnError: false
}, options)
var exec = function() {
var serial = self.serials.pop()
if(serial) {
serial.options = serial.options || {}
serial.options.before && serial.options.before(serial.klass)
var onSuccess = function() {
serial.options.after && serial.options.after(serial.klass)
self.finishedEmits++
exec()
}
var onError = function(err) {
serial.options.after && serial.options.after(serial.klass)
self.finishedEmits++
self.fails.push(err)
exec()
}
if(options.skipOnError && (self.fails.length > 0)) {
onError('Skipped due to earlier error!')
} else {
var emitter = serial.klass[serial.method].apply(serial.klass, serial.params)
emitter.success(function() {
if(serial.options.success)
serial.options.success(serial.klass, onSuccess)
else
onSuccess()
}).error(onError)
}
} else {
self.wasRunning = true
finish.call(self)
}
}
this.serials.reverse()
this.eventEmitter = new Utils.CustomEventEmitter(exec)
return this.eventEmitter.run()
}
// private
var observeEmitter = function(emitter) {
var self = this
emitter
.success(function(){
self.finishedEmits++
finish.call(self)
})
.error(function(err){
self.finishedEmits++
self.fails.push(err)
finish.call(self)
})
}
var finish = function() {
this.finished = true
if(this.emitters.length > 0)
this.finished = (this.finishedEmits == this.emitters.length)
else if(this.serials.length > 0)
this.finished = (this.finishedEmits == this.serials.length)
if(this.finished && this.wasRunning) {
var status = (this.fails.length == 0 ? 'success' : 'failure')
, result = (this.fails.length == 0 ? result : this.fails)
this.eventEmitter.emit(status, result)
}
}
return QueryChainer
})()