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 (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 |