-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathko.promise.js
108 lines (108 loc) · 3.84 KB
/
ko.promise.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
96
97
98
99
100
101
102
103
104
105
106
107
108
(function (global) {
var defineCallback = function (ko) {
var isPromise = function (obj) {
return !obj ? false : obj['then'];
};
var isKoPromise = function (obj) {
return isPromise(obj) && obj['loading'];
};
var then = function (source, doneHandler, failHandler, progressHandler) {
return factory(function (target) {
var value = source();
if (source['loading']() === false) {
target(doneHandler(value));
}
});
};
var when = function (source, promises) {
promises.push(source);
return factory(function (target) {
var resolvedPromiseCount = 0,
resolvePromise = function() {
resolvedPromiseCount++;
if(resolvedPromiseCount === promises.length) {
target(source());
}
};
for (var i = 0; i < promises.length; i++) {
promises[i]['then'](resolvePromise)();
}
this['loading']['subscribe'](function(isLoading) {
if(isLoading === false) {
for (var i = 0; i < promises.length; i++) {
if(isKoPromise(promises[i])) {
promises[i]();
}
}
}
});
});
};
var factory = function (source) {
var awaitingEvaluation = true,
loading = ko['observable'](false),
backing = ko['observable'](),
updateBacking = function (value) {
backing(value);
loading(false);
},
target = function (value) {
if (isPromise(value)) {
var promise = value['then'](function (result) {
updateBacking(result);
});
if (isKoPromise(value)) {
promise();
}
} else {
updateBacking(value);
}
};
var api = ko['computed']({
'read': function () {
if (awaitingEvaluation) {
awaitingEvaluation = false;
ko['computed'](function () {
loading(true);
source.apply(api, [target]);
});
}
return ko['utils']['unwrapObservable'](backing());
},
'deferEvaluation': true
});
api['loading'] = loading;
return api;
};
ko['promise'] = function (source) {
if (isPromise(source)) {
return factory(function (target) {
source['then'](function (data) {
target(data);
});
});
} else {
return factory(source);
}
};
ko['subscribable']['fn']['then'] = function (doneHandler, failHandler, progressHandler) {
var source = this;
if (isKoPromise(source)) {
return then(source, doneHandler, failHandler, progressHandler);
} else {
return factory(function (target) {
target(doneHandler(source()));
});
}
};
ko['subscribable']['fn']['when'] = function () {
var promises = Array.prototype.slice.call(arguments);
return when(this, promises);
};
};
if (typeof define === 'function' && define['amd']) {
define(['knockout'], defineCallback);
} else {
defineCallback(global['ko']);
}
})(this);