-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathpinkyswear.js
125 lines (120 loc) · 3.96 KB
/
pinkyswear.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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/*
* PinkySwear.js 2.2.2 - Minimalistic implementation of the Promises/A+ spec
*
* Public Domain. Use, modify and distribute it any way you like. No attribution required.
*
* NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
*
* PinkySwear is a very small implementation of the Promises/A+ specification. After compilation with the
* Google Closure Compiler and gzipping it weighs less than 500 bytes. It is based on the implementation for
* Minified.js and should be perfect for embedding.
*
*
* PinkySwear has just three functions.
*
* To create a new promise in pending state, call pinkySwear():
* var promise = pinkySwear();
*
* The returned object has a Promises/A+ compatible then() implementation:
* promise.then(function(value) { alert("Success!"); }, function(value) { alert("Failure!"); });
*
*
* The promise returned by pinkySwear() is a function. To fulfill the promise, call the function with true as first argument and
* an optional array of values to pass to the then() handler. By putting more than one value in the array, you can pass more than one
* value to the then() handlers. Here an example to fulfill a promsise, this time with only one argument:
* promise(true, [42]);
*
* When the promise has been rejected, call it with false. Again, there may be more than one argument for the then() handler:
* promise(true, [6, 6, 6]);
*
* You can obtain the promise's current state by calling the function without arguments. It will be true if fulfilled,
* false if rejected, and otherwise undefined.
* var state = promise();
*
* https://github.com/timjansen/PinkySwear.js
*/
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define([], factory);
} else if (typeof module === 'object' && module.exports) {
module.exports = factory();
} else {
root.pinkySwear = factory();
}
}(this, function() {
var undef;
function isFunction(f) {
return typeof f == 'function';
}
function isObject(f) {
return typeof f == 'object';
}
function defer(callback) {
if (typeof setImmediate != 'undefined')
setImmediate(callback);
else if (typeof process != 'undefined' && process['nextTick'])
process['nextTick'](callback);
else
setTimeout(callback, 0);
}
return function pinkySwear(extend) {
var state; // undefined/null = pending, true = fulfilled, false = rejected
var values = []; // an array of values as arguments for the then() handlers
var deferred = []; // functions to call when set() is invoked
var set = function(newState, newValues) {
if (state == null && newState != null) {
state = newState;
values = newValues;
if (deferred.length)
defer(function() {
for (var i = 0; i < deferred.length; i++)
deferred[i]();
});
}
return state;
};
set['then'] = function (onFulfilled, onRejected) {
var promise2 = pinkySwear(extend);
var callCallbacks = function() {
try {
var f = (state ? onFulfilled : onRejected);
if (isFunction(f)) {
function resolve(x) {
var then, cbCalled = 0;
try {
if (x && (isObject(x) || isFunction(x)) && isFunction(then = x['then'])) {
if (x === promise2)
throw new TypeError();
then['call'](x,
function() { if (!cbCalled++) resolve.apply(undef,arguments); } ,
function(value){ if (!cbCalled++) promise2(false,[value]);});
}
else
promise2(true, arguments);
}
catch(e) {
if (!cbCalled++)
promise2(false, [e]);
}
}
resolve(f.apply(undef, values || []));
}
else
promise2(state, values);
}
catch (e) {
promise2(false, [e]);
}
};
if (state != null)
defer(callCallbacks);
else
deferred.push(callCallbacks);
return promise2;
};
if(extend){
set = extend(set);
}
return set;
};
}));