Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 "use strict"; | 5 "use strict"; |
| 6 | 6 |
| 7 // This file relies on the fact that the following declaration has been made | 7 // This file relies on the fact that the following declaration has been made |
| 8 // in runtime.js: | 8 // in runtime.js: |
| 9 // var $Object = global.Object | 9 // var $Object = global.Object |
| 10 // var $WeakMap = global.WeakMap | 10 // var $WeakMap = global.WeakMap |
| 11 | 11 |
| 12 // For bootstrapper. | |
| 12 | 13 |
| 13 var $Promise = function Promise(resolver) { | 14 var IsPromise; |
| 14 if (resolver === promiseRaw) return; | 15 var PromiseCreate; |
| 15 if (!%_IsConstructCall()) throw MakeTypeError('not_a_promise', [this]); | 16 var PromiseResolve; |
| 16 if (!IS_SPEC_FUNCTION(resolver)) | 17 var PromiseReject; |
| 17 throw MakeTypeError('resolver_not_a_function', [resolver]); | 18 var PromiseChain; |
| 18 var promise = PromiseInit(this); | 19 var PromiseCatch; |
| 19 try { | |
| 20 %DebugPromiseHandlePrologue(function() { return promise }); | |
| 21 resolver(function(x) { PromiseResolve(promise, x) }, | |
| 22 function(r) { PromiseReject(promise, r) }); | |
| 23 } catch (e) { | |
| 24 PromiseReject(promise, e); | |
| 25 } finally { | |
| 26 %DebugPromiseHandleEpilogue(); | |
| 27 } | |
| 28 } | |
| 29 | |
| 30 | |
| 31 //------------------------------------------------------------------- | |
| 32 | |
| 33 // Core functionality. | |
| 34 | 20 |
| 35 // Status values: 0 = pending, +1 = resolved, -1 = rejected | 21 // Status values: 0 = pending, +1 = resolved, -1 = rejected |
| 36 var promiseStatus = GLOBAL_PRIVATE("Promise#status"); | 22 var promiseStatus = GLOBAL_PRIVATE("Promise#status"); |
|
rossberg
2014/05/22 13:23:05
Can't these go into the closure as well?
Jakob Kummerow
2014/05/22 13:54:58
Unfortunately no, because debugger. Added a TODO.
| |
| 37 var promiseValue = GLOBAL_PRIVATE("Promise#value"); | 23 var promiseValue = GLOBAL_PRIVATE("Promise#value"); |
| 38 var promiseOnResolve = GLOBAL_PRIVATE("Promise#onResolve"); | 24 var promiseOnResolve = GLOBAL_PRIVATE("Promise#onResolve"); |
| 39 var promiseOnReject = GLOBAL_PRIVATE("Promise#onReject"); | 25 var promiseOnReject = GLOBAL_PRIVATE("Promise#onReject"); |
| 40 var promiseRaw = GLOBAL_PRIVATE("Promise#raw"); | 26 var promiseRaw = GLOBAL_PRIVATE("Promise#raw"); |
| 41 | 27 |
| 42 function IsPromise(x) { | 28 (function() { |
| 43 return IS_SPEC_OBJECT(x) && %HasLocalProperty(x, promiseStatus); | 29 |
| 44 } | 30 var $Promise = function Promise(resolver) { |
| 45 | 31 if (resolver === promiseRaw) return; |
| 46 function PromiseSet(promise, status, value, onResolve, onReject) { | 32 if (!%_IsConstructCall()) throw MakeTypeError('not_a_promise', [this]); |
| 47 SET_PRIVATE(promise, promiseStatus, status); | 33 if (!IS_SPEC_FUNCTION(resolver)) |
| 48 SET_PRIVATE(promise, promiseValue, value); | 34 throw MakeTypeError('resolver_not_a_function', [resolver]); |
| 49 SET_PRIVATE(promise, promiseOnResolve, onResolve); | 35 var promise = PromiseInit(this); |
| 50 SET_PRIVATE(promise, promiseOnReject, onReject); | 36 try { |
| 51 return promise; | 37 %DebugPromiseHandlePrologue(function() { return promise }); |
| 52 } | 38 resolver(function(x) { PromiseResolve(promise, x) }, |
| 53 | 39 function(r) { PromiseReject(promise, r) }); |
| 54 function PromiseInit(promise) { | 40 } catch (e) { |
| 55 return PromiseSet(promise, 0, UNDEFINED, new InternalArray, new InternalArray) | 41 PromiseReject(promise, e); |
| 56 } | 42 } finally { |
| 57 | |
| 58 function PromiseDone(promise, status, value, promiseQueue) { | |
| 59 if (GET_PRIVATE(promise, promiseStatus) === 0) { | |
| 60 PromiseEnqueue(value, GET_PRIVATE(promise, promiseQueue)); | |
| 61 PromiseSet(promise, status, value); | |
| 62 } | |
| 63 } | |
| 64 | |
| 65 function PromiseResolve(promise, x) { | |
| 66 PromiseDone(promise, +1, x, promiseOnResolve) | |
| 67 } | |
| 68 | |
| 69 function PromiseReject(promise, r) { | |
| 70 PromiseDone(promise, -1, r, promiseOnReject) | |
| 71 } | |
| 72 | |
| 73 | |
| 74 // For API. | |
| 75 | |
| 76 function PromiseNopResolver() {} | |
| 77 | |
| 78 function PromiseCreate() { | |
| 79 return new $Promise(PromiseNopResolver) | |
| 80 } | |
| 81 | |
| 82 | |
| 83 // Convenience. | |
| 84 | |
| 85 function PromiseDeferred() { | |
| 86 if (this === $Promise) { | |
| 87 // Optimized case, avoid extra closure. | |
| 88 var promise = PromiseInit(new $Promise(promiseRaw)); | |
| 89 return { | |
| 90 promise: promise, | |
| 91 resolve: function(x) { PromiseResolve(promise, x) }, | |
| 92 reject: function(r) { PromiseReject(promise, r) } | |
| 93 }; | |
| 94 } else { | |
| 95 var result = {}; | |
| 96 result.promise = new this(function(resolve, reject) { | |
| 97 result.resolve = resolve; | |
| 98 result.reject = reject; | |
| 99 }) | |
| 100 return result; | |
| 101 } | |
| 102 } | |
| 103 | |
| 104 function PromiseResolved(x) { | |
| 105 if (this === $Promise) { | |
| 106 // Optimized case, avoid extra closure. | |
| 107 return PromiseSet(new $Promise(promiseRaw), +1, x); | |
| 108 } else { | |
| 109 return new this(function(resolve, reject) { resolve(x) }); | |
| 110 } | |
| 111 } | |
| 112 | |
| 113 function PromiseRejected(r) { | |
| 114 if (this === $Promise) { | |
| 115 // Optimized case, avoid extra closure. | |
| 116 return PromiseSet(new $Promise(promiseRaw), -1, r); | |
| 117 } else { | |
| 118 return new this(function(resolve, reject) { reject(r) }); | |
| 119 } | |
| 120 } | |
| 121 | |
| 122 | |
| 123 // Simple chaining. | |
| 124 | |
| 125 function PromiseIdResolveHandler(x) { return x } | |
| 126 function PromiseIdRejectHandler(r) { throw r } | |
| 127 | |
| 128 function PromiseChain(onResolve, onReject) { // a.k.a. flatMap | |
| 129 onResolve = IS_UNDEFINED(onResolve) ? PromiseIdResolveHandler : onResolve; | |
| 130 onReject = IS_UNDEFINED(onReject) ? PromiseIdRejectHandler : onReject; | |
| 131 var deferred = %_CallFunction(this.constructor, PromiseDeferred); | |
| 132 switch (GET_PRIVATE(this, promiseStatus)) { | |
| 133 case UNDEFINED: | |
| 134 throw MakeTypeError('not_a_promise', [this]); | |
| 135 case 0: // Pending | |
| 136 GET_PRIVATE(this, promiseOnResolve).push(onResolve, deferred); | |
| 137 GET_PRIVATE(this, promiseOnReject).push(onReject, deferred); | |
| 138 break; | |
| 139 case +1: // Resolved | |
| 140 PromiseEnqueue(GET_PRIVATE(this, promiseValue), [onResolve, deferred]); | |
| 141 break; | |
| 142 case -1: // Rejected | |
| 143 PromiseEnqueue(GET_PRIVATE(this, promiseValue), [onReject, deferred]); | |
| 144 break; | |
| 145 } | |
| 146 return deferred.promise; | |
| 147 } | |
| 148 | |
| 149 function PromiseCatch(onReject) { | |
| 150 return this.then(UNDEFINED, onReject); | |
| 151 } | |
| 152 | |
| 153 function PromiseEnqueue(value, tasks) { | |
| 154 %EnqueueMicrotask(function() { | |
| 155 for (var i = 0; i < tasks.length; i += 2) { | |
| 156 PromiseHandle(value, tasks[i], tasks[i + 1]) | |
| 157 } | |
| 158 }); | |
| 159 } | |
| 160 | |
| 161 function PromiseHandle(value, handler, deferred) { | |
| 162 try { | |
| 163 %DebugPromiseHandlePrologue( | |
| 164 function() { | |
| 165 var queue = GET_PRIVATE(deferred.promise, promiseOnReject); | |
| 166 return (queue && queue.length == 0) ? deferred.promise : UNDEFINED; | |
| 167 }); | |
| 168 var result = handler(value); | |
| 169 if (result === deferred.promise) | |
| 170 throw MakeTypeError('promise_cyclic', [result]); | |
| 171 else if (IsPromise(result)) | |
| 172 %_CallFunction(result, deferred.resolve, deferred.reject, PromiseChain); | |
| 173 else | |
| 174 deferred.resolve(result); | |
| 175 } catch (exception) { | |
| 176 try { | |
| 177 %DebugPromiseHandlePrologue(function() { return deferred.promise }); | |
| 178 deferred.reject(exception); | |
| 179 } catch (e) { } finally { | |
| 180 %DebugPromiseHandleEpilogue(); | 43 %DebugPromiseHandleEpilogue(); |
| 181 } | 44 } |
| 182 } finally { | 45 } |
| 183 %DebugPromiseHandleEpilogue(); | 46 |
| 184 } | 47 // Core functionality. |
| 185 } | 48 |
| 186 | 49 function PromiseSet(promise, status, value, onResolve, onReject) { |
| 187 | 50 SET_PRIVATE(promise, promiseStatus, status); |
| 188 // Multi-unwrapped chaining with thenable coercion. | 51 SET_PRIVATE(promise, promiseValue, value); |
| 189 | 52 SET_PRIVATE(promise, promiseOnResolve, onResolve); |
| 190 function PromiseThen(onResolve, onReject) { | 53 SET_PRIVATE(promise, promiseOnReject, onReject); |
| 191 onResolve = IS_SPEC_FUNCTION(onResolve) ? onResolve : PromiseIdResolveHandler; | 54 return promise; |
| 192 onReject = IS_SPEC_FUNCTION(onReject) ? onReject : PromiseIdRejectHandler; | 55 } |
| 193 var that = this; | 56 |
| 194 var constructor = this.constructor; | 57 function PromiseInit(promise) { |
| 195 return %_CallFunction( | 58 return PromiseSet(promise, 0, UNDEFINED, new InternalArray, |
| 196 this, | 59 new InternalArray) |
| 197 function(x) { | 60 } |
| 198 x = PromiseCoerce(constructor, x); | 61 |
| 199 return x === that ? onReject(MakeTypeError('promise_cyclic', [x])) : | 62 function PromiseDone(promise, status, value, promiseQueue) { |
| 200 IsPromise(x) ? x.then(onResolve, onReject) : onResolve(x); | 63 if (GET_PRIVATE(promise, promiseStatus) === 0) { |
| 201 }, | 64 PromiseEnqueue(value, GET_PRIVATE(promise, promiseQueue)); |
| 202 onReject, | 65 PromiseSet(promise, status, value); |
| 203 PromiseChain | 66 } |
| 204 ); | 67 } |
| 205 } | 68 |
| 206 | 69 function PromiseCoerce(constructor, x) { |
| 207 function PromiseCoerce(constructor, x) { | 70 if (!IsPromise(x) && IS_SPEC_OBJECT(x)) { |
| 208 if (!IsPromise(x) && IS_SPEC_OBJECT(x)) { | 71 var then; |
| 209 var then; | |
| 210 try { | |
| 211 then = x.then; | |
| 212 } catch(r) { | |
| 213 return %_CallFunction(constructor, r, PromiseRejected); | |
| 214 } | |
| 215 if (IS_SPEC_FUNCTION(then)) { | |
| 216 var deferred = %_CallFunction(constructor, PromiseDeferred); | |
| 217 try { | 72 try { |
| 218 %_CallFunction(x, deferred.resolve, deferred.reject, then); | 73 then = x.then; |
| 219 } catch(r) { | 74 } catch(r) { |
| 220 deferred.reject(r); | 75 return %_CallFunction(constructor, r, PromiseRejected); |
| 221 } | 76 } |
| 77 if (IS_SPEC_FUNCTION(then)) { | |
| 78 var deferred = %_CallFunction(constructor, PromiseDeferred); | |
| 79 try { | |
| 80 %_CallFunction(x, deferred.resolve, deferred.reject, then); | |
| 81 } catch(r) { | |
| 82 deferred.reject(r); | |
| 83 } | |
| 84 return deferred.promise; | |
| 85 } | |
| 86 } | |
| 87 return x; | |
| 88 } | |
| 89 | |
| 90 function PromiseHandle(value, handler, deferred) { | |
| 91 try { | |
| 92 %DebugPromiseHandlePrologue( | |
| 93 function() { | |
| 94 var queue = GET_PRIVATE(deferred.promise, promiseOnReject); | |
| 95 return (queue && queue.length == 0) ? deferred.promise : UNDEFINED; | |
| 96 }); | |
| 97 var result = handler(value); | |
| 98 if (result === deferred.promise) | |
| 99 throw MakeTypeError('promise_cyclic', [result]); | |
| 100 else if (IsPromise(result)) | |
| 101 %_CallFunction(result, deferred.resolve, deferred.reject, PromiseChain); | |
| 102 else | |
| 103 deferred.resolve(result); | |
| 104 } catch (exception) { | |
| 105 try { | |
| 106 %DebugPromiseHandlePrologue(function() { return deferred.promise }); | |
| 107 deferred.reject(exception); | |
| 108 } catch (e) { } finally { | |
| 109 %DebugPromiseHandleEpilogue(); | |
| 110 } | |
| 111 } finally { | |
| 112 %DebugPromiseHandleEpilogue(); | |
| 113 } | |
| 114 } | |
| 115 | |
| 116 function PromiseEnqueue(value, tasks) { | |
| 117 %EnqueueMicrotask(function() { | |
| 118 for (var i = 0; i < tasks.length; i += 2) { | |
| 119 PromiseHandle(value, tasks[i], tasks[i + 1]) | |
| 120 } | |
| 121 }); | |
| 122 } | |
| 123 | |
| 124 function PromiseIdResolveHandler(x) { return x } | |
| 125 function PromiseIdRejectHandler(r) { throw r } | |
| 126 | |
| 127 function PromiseNopResolver() {} | |
| 128 | |
| 129 // ------------------------------------------------------------------- | |
| 130 // Define exported functions. | |
| 131 | |
| 132 // For bootstrapper. | |
| 133 | |
| 134 IsPromise = function IsPromise(x) { | |
| 135 return IS_SPEC_OBJECT(x) && %HasLocalProperty(x, promiseStatus); | |
| 136 } | |
| 137 | |
| 138 PromiseCreate = function PromiseCreate() { | |
| 139 return new $Promise(PromiseNopResolver) | |
| 140 } | |
| 141 | |
| 142 PromiseResolve = function PromiseResolve(promise, x) { | |
| 143 PromiseDone(promise, +1, x, promiseOnResolve) | |
| 144 } | |
| 145 | |
| 146 PromiseReject = function PromiseReject(promise, r) { | |
| 147 PromiseDone(promise, -1, r, promiseOnReject) | |
| 148 } | |
| 149 | |
| 150 // Convenience. | |
| 151 | |
| 152 function PromiseDeferred() { | |
| 153 if (this === $Promise) { | |
| 154 // Optimized case, avoid extra closure. | |
| 155 var promise = PromiseInit(new $Promise(promiseRaw)); | |
| 156 return { | |
| 157 promise: promise, | |
| 158 resolve: function(x) { PromiseResolve(promise, x) }, | |
| 159 reject: function(r) { PromiseReject(promise, r) } | |
| 160 }; | |
| 161 } else { | |
| 162 var result = {}; | |
| 163 result.promise = new this(function(resolve, reject) { | |
| 164 result.resolve = resolve; | |
| 165 result.reject = reject; | |
| 166 }) | |
| 167 return result; | |
| 168 } | |
| 169 } | |
| 170 | |
| 171 function PromiseResolved(x) { | |
| 172 if (this === $Promise) { | |
| 173 // Optimized case, avoid extra closure. | |
| 174 return PromiseSet(new $Promise(promiseRaw), +1, x); | |
| 175 } else { | |
| 176 return new this(function(resolve, reject) { resolve(x) }); | |
| 177 } | |
| 178 } | |
| 179 | |
| 180 function PromiseRejected(r) { | |
| 181 if (this === $Promise) { | |
| 182 // Optimized case, avoid extra closure. | |
| 183 return PromiseSet(new $Promise(promiseRaw), -1, r); | |
| 184 } else { | |
| 185 return new this(function(resolve, reject) { reject(r) }); | |
| 186 } | |
| 187 } | |
| 188 | |
| 189 // Simple chaining. | |
| 190 | |
| 191 PromiseChain = function PromiseChain(onResolve, onReject) { // a.k.a. | |
| 192 // flatMap | |
| 193 onResolve = IS_UNDEFINED(onResolve) ? PromiseIdResolveHandler : onResolve; | |
| 194 onReject = IS_UNDEFINED(onReject) ? PromiseIdRejectHandler : onReject; | |
| 195 var deferred = %_CallFunction(this.constructor, PromiseDeferred); | |
| 196 switch (GET_PRIVATE(this, promiseStatus)) { | |
| 197 case UNDEFINED: | |
| 198 throw MakeTypeError('not_a_promise', [this]); | |
| 199 case 0: // Pending | |
| 200 GET_PRIVATE(this, promiseOnResolve).push(onResolve, deferred); | |
| 201 GET_PRIVATE(this, promiseOnReject).push(onReject, deferred); | |
| 202 break; | |
| 203 case +1: // Resolved | |
| 204 PromiseEnqueue(GET_PRIVATE(this, promiseValue), [onResolve, deferred]); | |
| 205 break; | |
| 206 case -1: // Rejected | |
| 207 PromiseEnqueue(GET_PRIVATE(this, promiseValue), [onReject, deferred]); | |
| 208 break; | |
| 209 } | |
| 210 return deferred.promise; | |
| 211 } | |
| 212 | |
| 213 PromiseCatch = function PromiseCatch(onReject) { | |
| 214 return this.then(UNDEFINED, onReject); | |
| 215 } | |
| 216 | |
| 217 // Multi-unwrapped chaining with thenable coercion. | |
| 218 | |
| 219 function PromiseThen(onResolve, onReject) { | |
| 220 onResolve = IS_SPEC_FUNCTION(onResolve) ? onResolve | |
| 221 : PromiseIdResolveHandler; | |
| 222 onReject = IS_SPEC_FUNCTION(onReject) ? onReject | |
| 223 : PromiseIdRejectHandler; | |
| 224 var that = this; | |
| 225 var constructor = this.constructor; | |
| 226 return %_CallFunction( | |
| 227 this, | |
| 228 function(x) { | |
| 229 x = PromiseCoerce(constructor, x); | |
| 230 return x === that ? onReject(MakeTypeError('promise_cyclic', [x])) : | |
| 231 IsPromise(x) ? x.then(onResolve, onReject) : onResolve(x); | |
| 232 }, | |
| 233 onReject, | |
| 234 PromiseChain | |
| 235 ); | |
| 236 } | |
| 237 | |
| 238 // Combinators. | |
| 239 | |
| 240 function PromiseCast(x) { | |
| 241 // TODO(rossberg): cannot do better until we support @@create. | |
| 242 return IsPromise(x) ? x : new this(function(resolve) { resolve(x) }); | |
| 243 } | |
| 244 | |
| 245 function PromiseAll(values) { | |
| 246 var deferred = %_CallFunction(this, PromiseDeferred); | |
| 247 var resolutions = []; | |
| 248 if (!%_IsArray(values)) { | |
| 249 deferred.reject(MakeTypeError('invalid_argument')); | |
| 222 return deferred.promise; | 250 return deferred.promise; |
| 223 } | 251 } |
| 224 } | 252 try { |
| 225 return x; | 253 var count = values.length; |
| 226 } | 254 if (count === 0) { |
| 227 | 255 deferred.resolve(resolutions); |
| 228 | 256 } else { |
| 229 // Combinators. | 257 for (var i = 0; i < values.length; ++i) { |
| 230 | 258 this.resolve(values[i]).then( |
| 231 function PromiseCast(x) { | 259 function(i, x) { |
| 232 // TODO(rossberg): cannot do better until we support @@create. | 260 resolutions[i] = x; |
| 233 return IsPromise(x) ? x : new this(function(resolve) { resolve(x) }); | 261 if (--count === 0) deferred.resolve(resolutions); |
| 234 } | 262 }.bind(UNDEFINED, i), // TODO(rossberg): use let loop once |
| 235 | 263 // available |
| 236 function PromiseAll(values) { | 264 function(r) { deferred.reject(r) } |
| 237 var deferred = %_CallFunction(this, PromiseDeferred); | 265 ); |
| 238 var resolutions = []; | 266 } |
| 239 if (!%_IsArray(values)) { | 267 } |
| 240 deferred.reject(MakeTypeError('invalid_argument')); | 268 } catch (e) { |
| 269 deferred.reject(e) | |
| 270 } | |
| 241 return deferred.promise; | 271 return deferred.promise; |
| 242 } | 272 } |
| 243 try { | 273 |
| 244 var count = values.length; | 274 function PromiseOne(values) { |
| 245 if (count === 0) { | 275 var deferred = %_CallFunction(this, PromiseDeferred); |
| 246 deferred.resolve(resolutions); | 276 if (!%_IsArray(values)) { |
| 247 } else { | 277 deferred.reject(MakeTypeError('invalid_argument')); |
| 278 return deferred.promise; | |
| 279 } | |
| 280 try { | |
| 248 for (var i = 0; i < values.length; ++i) { | 281 for (var i = 0; i < values.length; ++i) { |
| 249 this.resolve(values[i]).then( | 282 this.resolve(values[i]).then( |
| 250 function(i, x) { | 283 function(x) { deferred.resolve(x) }, |
| 251 resolutions[i] = x; | |
| 252 if (--count === 0) deferred.resolve(resolutions); | |
| 253 }.bind(UNDEFINED, i), // TODO(rossberg): use let loop once available | |
| 254 function(r) { deferred.reject(r) } | 284 function(r) { deferred.reject(r) } |
| 255 ); | 285 ); |
| 256 } | 286 } |
| 257 } | 287 } catch (e) { |
| 258 } catch (e) { | 288 deferred.reject(e) |
| 259 deferred.reject(e) | 289 } |
| 260 } | |
| 261 return deferred.promise; | |
| 262 } | |
| 263 | |
| 264 function PromiseOne(values) { | |
| 265 var deferred = %_CallFunction(this, PromiseDeferred); | |
| 266 if (!%_IsArray(values)) { | |
| 267 deferred.reject(MakeTypeError('invalid_argument')); | |
| 268 return deferred.promise; | 290 return deferred.promise; |
| 269 } | 291 } |
| 270 try { | 292 |
| 271 for (var i = 0; i < values.length; ++i) { | 293 // ------------------------------------------------------------------- |
| 272 this.resolve(values[i]).then( | 294 // Install exported functions. |
| 273 function(x) { deferred.resolve(x) }, | 295 |
| 274 function(r) { deferred.reject(r) } | |
| 275 ); | |
| 276 } | |
| 277 } catch (e) { | |
| 278 deferred.reject(e) | |
| 279 } | |
| 280 return deferred.promise; | |
| 281 } | |
| 282 | |
| 283 //------------------------------------------------------------------- | |
| 284 | |
| 285 function SetUpPromise() { | |
| 286 %CheckIsBootstrapping(); | 296 %CheckIsBootstrapping(); |
| 287 %SetProperty(global, 'Promise', $Promise, DONT_ENUM); | 297 %SetProperty(global, 'Promise', $Promise, DONT_ENUM); |
| 288 InstallFunctions($Promise, DONT_ENUM, [ | 298 InstallFunctions($Promise, DONT_ENUM, [ |
| 289 "defer", PromiseDeferred, | 299 "defer", PromiseDeferred, |
| 290 "accept", PromiseResolved, | 300 "accept", PromiseResolved, |
| 291 "reject", PromiseRejected, | 301 "reject", PromiseRejected, |
| 292 "all", PromiseAll, | 302 "all", PromiseAll, |
| 293 "race", PromiseOne, | 303 "race", PromiseOne, |
| 294 "resolve", PromiseCast | 304 "resolve", PromiseCast |
| 295 ]); | 305 ]); |
| 296 InstallFunctions($Promise.prototype, DONT_ENUM, [ | 306 InstallFunctions($Promise.prototype, DONT_ENUM, [ |
| 297 "chain", PromiseChain, | 307 "chain", PromiseChain, |
| 298 "then", PromiseThen, | 308 "then", PromiseThen, |
| 299 "catch", PromiseCatch | 309 "catch", PromiseCatch |
| 300 ]); | 310 ]); |
| 301 } | |
| 302 | 311 |
| 303 SetUpPromise(); | 312 })(); |
| OLD | NEW |