-
Notifications
You must be signed in to change notification settings - Fork 0
/
simpleDeferred.js
83 lines (73 loc) · 2.45 KB
/
simpleDeferred.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
var deferred = function() {
var value,
callbacks = [],
applyCallbacks = function() {
_.each(callbacks, function(callback) {
callback.fn.call(
callback.scope || window,
value
);
});
callbacks = [];
};
return {
done: function(callback, scope) {
if (!_.isFunction(callback)) {
throw new Error('Error in deferred.done(): first argument should be a function!');
}
if (value) {
callback.call(scope, value);
} else {
callbacks.push({
fn: callback,
scope: scope
});
}
},
resolve: function(val) {
value = val;
applyCallbacks();
},
// For internal use inside when() only!
getCurrentValue: function() {
return value;
}
}
};
var when = function() {
var firstDeferred = _.first(arguments),
restOfDeferreds = _.rest(arguments, 1);
if (
!_.isFunction(firstDeferred.done) ||
!_.isFunction(firstDeferred.resolve) ||
!_.isFunction(firstDeferred.getCurrentValue)
) {
throw new Error('Error in when(): all the arguments should be deferreds!');
}
return {
done: function(callback, scope) {
if (!_.isFunction(callback)) {
throw new Error('Error in when.done(): first argument should be a function!');
}
firstDeferred.done(function(value) {
if (!restOfDeferreds.length) {
callback.call(scope, value);
} else {
when.apply(null, restOfDeferreds).done(function() {
callback.apply(
scope,
[].concat(
[ firstDeferred.getCurrentValue() ],
// transforming "arguments" variable to a real array
// ("arguments" is not an array, and concat() doesn't work with it properly)
_.map(arguments, function(arg) {
return arg;
})
)
);
}, scope);
}
});
}
}
}