-
Notifications
You must be signed in to change notification settings - Fork 30
/
Copy pathchaining.js
94 lines (76 loc) · 1.83 KB
/
chaining.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
function decorate (initial, decorate_before, decorate_after) {
return function () {
var initial_call_result;
if (typeof decorate_before === 'function') {
if (!!decorate_before.apply(this, arguments) === false) {
return;
}
}
initial_call_result = initial.apply(this, arguments);
if (typeof decorate_after === 'function') {
decorate_after.apply(this, arguments);
}
return initial_call_result;
};
}
function chain (func, callback) {
var callbacks,
func_states;
callbacks = [];
func_states = [];
chain = function (func, callback) {
var callback_index,
chained,
func_index;
callback_index = callbacks.indexOf(callback);
if (callback_index === -1) {
chained = {
func : [],
state : [],
test : function () {
for (var i = 0; i < this.func.length; i += 1) {
if (!this.state[i]) {
return;
}
}
callback();
this.state = [];
}
};
callbacks.push(callback);
func_states.push(chained);
} else {
chained = func_states[callback_index];
}
func_index = chained.func.push(func) - 1;
func = decorate(func, null, function () {
chained.state[func_index] = true;
chained.test();
});
return func;
};
return chain.apply(this, arguments);
}
/* example of use */
function on_all_async_ready () {
console.log('all ready');
}
var on_2_of_3_ready = function () {
console.info('1 and 2 ready');
}
var async_1 = chain(function () {
console.info('first async');
}, on_all_async_ready);
async_1 = chain(async_1, on_2_of_3_ready);
var async_2 = chain(function () {
console.info('second_async');
}, on_all_async_ready);
async_2 = chain(async_2, on_2_of_3_ready);
var async_3 = chain(function () {
console.info('third async');
}, on_all_async_ready);
setTimeout(function () {
async_1();
setTimeout(async_2, 1000);
setTimeout(async_3, 2000);
}, 2000);