-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathzhain.js
95 lines (80 loc) · 2.18 KB
/
zhain.js
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
function zhain() {
var empty = Object.create(Zhain.prototype)
empty.invoke = function(ctx, done) { done() }
return empty
}
function Zhain(parent, fn) {
this.parent = parent
this.fn = fn
}
;(function() {
Zhain.prototype.do = function(fn) {
return new Zhain(this, fn)
}
Zhain.prototype.sync = function(fn) {
return this.do(wrapSyncFn(fn))
}
Zhain.prototype.end = function() {
var me = this
return function(callback) {
var ctx = Object.create(Zhain.prototype)
ctx.context = this
return me.invoke.apply(me, [ctx, callback])
}
}
Zhain.prototype.run = function(callback) {
var ctx = Object.create(Zhain.prototype)
this.invoke(ctx, callback)
}
Zhain.prototype.invoke = function(ctx, callback) {
var done = allowOnce(callback || function() {}, ctx)
var fn = this.fn.length > 0 ? this.fn : wrapSyncFn(this.fn)
this.parent.invoke(ctx, function() {
var args = [].slice.call(arguments)
if (args[0]) {
done.apply(ctx, args)
} else {
fn.apply(ctx, args.slice(1).concat([done]))
}
})
}
Zhain.prototype.log = function(string) {
return this.sync(function() { console.log(string || arguments) })
}
Zhain.prototype.sleep = function(ms) {
return this.do(function(done) {
var args = splitArgs(arguments)
setTimeout(function() { args.done.apply(this, [null].concat(args.args)) }, ms)
})
}
Zhain.prototype.map = function(fn) {
return this.do(wrapSyncFn(fn))
}
zhain.prototype = Zhain.prototype
function wrapSyncFn(fn) {
return function(done) {
var args = splitArgs(arguments)
try {
var result = fn.apply(this, args.args)
result !== undefined ? args.done(null, result) : args.done(null)
} catch (e) {
args.done(e)
}
}
}
function allowOnce(fn, ctx) {
var invoked = false
return function() {
if (invoked) return
invoked = true
fn.apply(ctx, arguments)
}
}
function splitArgs(args) {
var all = [].slice.call(args)
return { args: all.slice(0, -1), done: all[all.length - 1] }
}
})()
if (typeof module !== 'undefined' && module.exports) {
module.exports = zhain
}