]>
git.proxmox.com Git - mirror_novnc.git/blob - vendor/promise.js
1 /* Copyright (c) 2014 Taylor Hakes
2 * Copyright (c) 2014 Forbes Lindesay
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 // Store setTimeout reference so promise-polyfill will be unaffected by
26 // other code modifying setTimeout (like sinon.useFakeTimers())
27 var setTimeoutFunc
= setTimeout
;
31 // Polyfill for Function.prototype.bind
32 function bind(fn
, thisArg
) {
34 fn
.apply(thisArg
, arguments
);
38 function Promise(fn
) {
39 if (typeof this !== 'object') throw new TypeError('Promises must be constructed via new');
40 if (typeof fn
!== 'function') throw new TypeError('not a function');
42 this._handled
= false;
43 this._value
= undefined;
49 function handle(self
, deferred
) {
50 while (self
._state
=== 3) {
53 if (self
._state
=== 0) {
54 self
._deferreds
.push(deferred
);
58 Promise
._immediateFn(function () {
59 var cb
= self
._state
=== 1 ? deferred
.onFulfilled
: deferred
.onRejected
;
61 (self
._state
=== 1 ? resolve
: reject
)(deferred
.promise
, self
._value
);
66 ret
= cb(self
._value
);
68 reject(deferred
.promise
, e
);
71 resolve(deferred
.promise
, ret
);
75 function resolve(self
, newValue
) {
77 // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
78 if (newValue
=== self
) throw new TypeError('A promise cannot be resolved with itself.');
79 if (newValue
&& (typeof newValue
=== 'object' || typeof newValue
=== 'function')) {
80 var then
= newValue
.then
;
81 if (newValue
instanceof Promise
) {
83 self
._value
= newValue
;
86 } else if (typeof then
=== 'function') {
87 doResolve(bind(then
, newValue
), self
);
92 self
._value
= newValue
;
99 function reject(self
, newValue
) {
101 self
._value
= newValue
;
105 function finale(self
) {
106 if (self
._state
=== 2 && self
._deferreds
.length
=== 0) {
107 Promise
._immediateFn(function() {
108 if (!self
._handled
) {
109 Promise
._unhandledRejectionFn(self
._value
);
114 for (var i
= 0, len
= self
._deferreds
.length
; i
< len
; i
++) {
115 handle(self
, self
._deferreds
[i
]);
117 self
._deferreds
= null;
120 function Handler(onFulfilled
, onRejected
, promise
) {
121 this.onFulfilled
= typeof onFulfilled
=== 'function' ? onFulfilled
: null;
122 this.onRejected
= typeof onRejected
=== 'function' ? onRejected
: null;
123 this.promise
= promise
;
127 * Take a potentially misbehaving resolver function and make sure
128 * onFulfilled and onRejected are only called once.
130 * Makes no guarantees about asynchrony.
132 function doResolve(fn
, self
) {
135 fn(function (value
) {
138 resolve(self
, value
);
139 }, function (reason
) {
142 reject(self
, reason
);
151 Promise
.prototype['catch'] = function (onRejected
) {
152 return this.then(null, onRejected
);
155 Promise
.prototype.then = function (onFulfilled
, onRejected
) {
156 var prom
= new (this.constructor)(noop
);
158 handle(this, new Handler(onFulfilled
, onRejected
, prom
));
162 Promise
.all = function (arr
) {
163 var args
= Array
.prototype.slice
.call(arr
);
165 return new Promise(function (resolve
, reject
) {
166 if (args
.length
=== 0) return resolve([]);
167 var remaining
= args
.length
;
169 function res(i
, val
) {
171 if (val
&& (typeof val
=== 'object' || typeof val
=== 'function')) {
173 if (typeof then
=== 'function') {
174 then
.call(val
, function (val
) {
181 if (--remaining
=== 0) {
189 for (var i
= 0; i
< args
.length
; i
++) {
195 Promise
.resolve = function (value
) {
196 if (value
&& typeof value
=== 'object' && value
.constructor === Promise
) {
200 return new Promise(function (resolve
) {
205 Promise
.reject = function (value
) {
206 return new Promise(function (resolve
, reject
) {
211 Promise
.race = function (values
) {
212 return new Promise(function (resolve
, reject
) {
213 for (var i
= 0, len
= values
.length
; i
< len
; i
++) {
214 values
[i
].then(resolve
, reject
);
219 // Use polyfill for setImmediate for performance gains
220 Promise
._immediateFn
= (typeof setImmediate
=== 'function' && function (fn
) { setImmediate(fn
); }) ||
222 setTimeoutFunc(fn
, 0);
225 Promise
._unhandledRejectionFn
= function _unhandledRejectionFn(err
) {
226 if (typeof console
!== 'undefined' && console
) {
227 console
.warn('Possible Unhandled Promise Rejection:', err
); // eslint-disable-line no-console
232 * Set the immediate function to execute callbacks
233 * @param fn {function} Function to execute
236 Promise
._setImmediateFn
= function _setImmediateFn(fn
) {
237 Promise
._immediateFn
= fn
;
241 * Change the function to execute on unhandled rejection
242 * @param {function} fn Function to execute on unhandled rejection
245 Promise
._setUnhandledRejectionFn
= function _setUnhandledRejectionFn(fn
) {
246 Promise
._unhandledRejectionFn
= fn
;
249 if (typeof module
!== 'undefined' && module
.exports
) {
250 module
.exports
= Promise
;
251 } else if (!root
.Promise
) {
252 root
.Promise
= Promise
;