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 (function(global, utils, extrasUtils) { | 5 (function(global, utils, extrasUtils) { |
6 | 6 |
7 "use strict"; | 7 "use strict"; |
8 | 8 |
9 %CheckIsBootstrapping(); | 9 %CheckIsBootstrapping(); |
10 | 10 |
11 // ------------------------------------------------------------------- | 11 // ------------------------------------------------------------------- |
12 // Imports | 12 // Imports |
13 | 13 |
14 var InternalArray = utils.InternalArray; | 14 var InternalArray = utils.InternalArray; |
15 var promiseCombinedDeferredSymbol = | |
16 utils.ImportNow("promise_combined_deferred_symbol"); | |
15 var promiseHasHandlerSymbol = | 17 var promiseHasHandlerSymbol = |
16 utils.ImportNow("promise_has_handler_symbol"); | 18 utils.ImportNow("promise_has_handler_symbol"); |
17 var promiseOnRejectSymbol = utils.ImportNow("promise_on_reject_symbol"); | 19 var promiseOnRejectSymbol = utils.ImportNow("promise_on_reject_symbol"); |
18 var promiseOnResolveSymbol = | 20 var promiseOnResolveSymbol = |
19 utils.ImportNow("promise_on_resolve_symbol"); | 21 utils.ImportNow("promise_on_resolve_symbol"); |
20 var promiseRawSymbol = utils.ImportNow("promise_raw_symbol"); | 22 var promiseRawSymbol = utils.ImportNow("promise_raw_symbol"); |
21 var promiseStatusSymbol = utils.ImportNow("promise_status_symbol"); | 23 var promiseStatusSymbol = utils.ImportNow("promise_status_symbol"); |
22 var promiseValueSymbol = utils.ImportNow("promise_value_symbol"); | 24 var promiseValueSymbol = utils.ImportNow("promise_value_symbol"); |
23 var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol"); | 25 var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol"); |
24 | 26 |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
291 } | 293 } |
292 } | 294 } |
293 | 295 |
294 function PromiseAll(iterable) { | 296 function PromiseAll(iterable) { |
295 var deferred = %_CallFunction(this, PromiseDeferred); | 297 var deferred = %_CallFunction(this, PromiseDeferred); |
296 var resolutions = []; | 298 var resolutions = []; |
297 try { | 299 try { |
298 var count = 0; | 300 var count = 0; |
299 var i = 0; | 301 var i = 0; |
300 for (var value of iterable) { | 302 for (var value of iterable) { |
303 var reject = function(r) { deferred.reject(r) }; | |
301 this.resolve(value).then( | 304 this.resolve(value).then( |
302 // Nested scope to get closure over current i. | 305 // Nested scope to get closure over current i. |
303 // TODO(arv): Use an inner let binding once available. | 306 // TODO(arv): Use an inner let binding once available. |
304 (function(i) { | 307 (function(i) { |
305 return function(x) { | 308 return function(x) { |
306 resolutions[i] = x; | 309 resolutions[i] = x; |
307 if (--count === 0) deferred.resolve(resolutions); | 310 if (--count === 0) deferred.resolve(resolutions); |
308 } | 311 } |
309 })(i), | 312 })(i), reject); |
310 function(r) { deferred.reject(r); }); | 313 SET_PRIVATE(reject, promiseCombinedDeferredSymbol, deferred); |
311 ++i; | 314 ++i; |
312 ++count; | 315 ++count; |
313 } | 316 } |
314 | 317 |
315 if (count === 0) { | 318 if (count === 0) { |
316 deferred.resolve(resolutions); | 319 deferred.resolve(resolutions); |
317 } | 320 } |
318 | 321 |
319 } catch (e) { | 322 } catch (e) { |
320 deferred.reject(e) | 323 deferred.reject(e) |
321 } | 324 } |
322 return deferred.promise; | 325 return deferred.promise; |
323 } | 326 } |
324 | 327 |
325 function PromiseRace(iterable) { | 328 function PromiseRace(iterable) { |
326 var deferred = %_CallFunction(this, PromiseDeferred); | 329 var deferred = %_CallFunction(this, PromiseDeferred); |
327 try { | 330 try { |
328 for (var value of iterable) { | 331 for (var value of iterable) { |
329 this.resolve(value).then( | 332 var reject = function(r) { deferred.reject(r) }; |
330 function(x) { deferred.resolve(x) }, | 333 this.resolve(value).then(function(x) { deferred.resolve(x) }, reject); |
Yang
2015/10/20 05:15:49
then() may not even return a Promise, if it's over
| |
331 function(r) { deferred.reject(r) }); | 334 SET_PRIVATE(reject, promiseCombinedDeferredSymbol, deferred); |
332 } | 335 } |
333 } catch (e) { | 336 } catch (e) { |
334 deferred.reject(e) | 337 deferred.reject(e) |
335 } | 338 } |
336 return deferred.promise; | 339 return deferred.promise; |
337 } | 340 } |
338 | 341 |
339 | 342 |
340 // Utility for debugger | 343 // Utility for debugger |
341 | 344 |
342 function PromiseHasUserDefinedRejectHandlerRecursive(promise) { | 345 function PromiseHasUserDefinedRejectHandlerRecursive(promise) { |
343 var queue = GET_PRIVATE(promise, promiseOnRejectSymbol); | 346 var queue = GET_PRIVATE(promise, promiseOnRejectSymbol); |
344 if (IS_UNDEFINED(queue)) return false; | 347 if (IS_UNDEFINED(queue)) return false; |
345 for (var i = 0; i < queue.length; i += 2) { | 348 for (var i = 0; i < queue.length; i += 2) { |
346 if (queue[i] != PromiseIdRejectHandler) return true; | 349 var handler = queue[i]; |
347 if (PromiseHasUserDefinedRejectHandlerRecursive(queue[i + 1].promise)) { | 350 if (handler !== PromiseIdRejectHandler) { |
351 var deferred = GET_PRIVATE(handler, promiseCombinedDeferredSymbol); | |
352 if (IS_UNDEFINED(deferred)) return true; | |
353 if (PromiseHasUserDefinedRejectHandlerRecursive(deferred.promise)) { | |
354 return true; | |
355 } | |
356 } else if (PromiseHasUserDefinedRejectHandlerRecursive( | |
357 queue[i + 1].promise)) { | |
348 return true; | 358 return true; |
349 } | 359 } |
350 } | 360 } |
351 return false; | 361 return false; |
352 } | 362 } |
353 | 363 |
354 // Return whether the promise will be handled by a user-defined reject | 364 // Return whether the promise will be handled by a user-defined reject |
355 // handler somewhere down the promise chain. For this, we do a depth-first | 365 // handler somewhere down the promise chain. For this, we do a depth-first |
356 // search for a reject handler that's not the default PromiseIdRejectHandler. | 366 // search for a reject handler that's not the default PromiseIdRejectHandler. |
357 function PromiseHasUserDefinedRejectHandler() { | 367 function PromiseHasUserDefinedRejectHandler() { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
393 // This allows extras to create promises quickly without building extra | 403 // This allows extras to create promises quickly without building extra |
394 // resolve/reject closures, and allows them to later resolve and reject any | 404 // resolve/reject closures, and allows them to later resolve and reject any |
395 // promise without having to hold on to those closures forever. | 405 // promise without having to hold on to those closures forever. |
396 utils.InstallFunctions(extrasUtils, 0, [ | 406 utils.InstallFunctions(extrasUtils, 0, [ |
397 "createPromise", PromiseCreate, | 407 "createPromise", PromiseCreate, |
398 "resolvePromise", PromiseResolve, | 408 "resolvePromise", PromiseResolve, |
399 "rejectPromise", PromiseReject | 409 "rejectPromise", PromiseReject |
400 ]); | 410 ]); |
401 | 411 |
402 }) | 412 }) |
OLD | NEW |