Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(820)

Unified Diff: src/js/promise.js

Issue 1534813005: [promise] Make Promise.all match spec, and always respect [[AlreadyResolved]] (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Remove "append NULL" since it doesn't seem to be needed, rearrange code Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | test/test262/test262.status » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/js/promise.js
diff --git a/src/js/promise.js b/src/js/promise.js
index 4db36359db1eb54de012183914ff4d7e707eef1d..b9100513ae1c6155abc0158acde2d602f7583a3e 100644
--- a/src/js/promise.js
+++ b/src/js/promise.js
@@ -66,13 +66,13 @@ var GlobalPromise = function Promise(resolver) {
throw MakeTypeError(kResolverNotAFunction, resolver);
var promise = PromiseInit(%NewObject(GlobalPromise, new.target));
+ var callbacks = CreateResolvingFunctions(promise);
try {
%DebugPushPromise(promise, Promise);
- var callbacks = CreateResolvingFunctions(promise);
resolver(callbacks.resolve, callbacks.reject);
} catch (e) {
- PromiseReject(promise, e);
+ %_Call(callbacks.reject, UNDEFINED, e);
} finally {
%DebugPopPromise();
}
@@ -181,11 +181,11 @@ function PromiseResolve(promise, x) {
if (instrumenting) {
%DebugAsyncTaskEvent({ type: "willHandle", id: id, name: name });
}
+ var callbacks = CreateResolvingFunctions(promise);
try {
- var callbacks = CreateResolvingFunctions(promise);
%_Call(then, x, callbacks.resolve, callbacks.reject);
} catch (e) {
- PromiseReject(promise, e);
+ %_Call(callbacks.reject, UNDEFINED, e);
}
if (instrumenting) {
%DebugAsyncTaskEvent({ type: "didHandle", id: id, name: name });
@@ -338,33 +338,50 @@ function PromiseCast(x) {
}
function PromiseAll(iterable) {
+ if (!IS_RECEIVER(this)) {
+ throw MakeTypeError(kCalledOnNonObject, "Promise.all");
+ }
+
var deferred = NewPromiseCapability(this);
- var resolutions = [];
+ var resolutions = new InternalArray();
+ var count;
+
+ function CreateResolveElementFunction(index, values, promiseCapability) {
+ var alreadyCalled = false;
+ return function(x) {
+ if (alreadyCalled === true) return;
+ alreadyCalled = true;
+ values[index] = x;
+ if (--count === 0) {
+ var valuesArray = [];
+ %MoveArrayContents(values, valuesArray);
+ %_Call(promiseCapability.resolve, UNDEFINED, valuesArray);
+ }
+ };
+ }
+
try {
- var count = 0;
var i = 0;
+ count = 1;
for (var value of iterable) {
- var reject = function(r) { deferred.reject(r) };
- this.resolve(value).then(
- // Nested scope to get closure over current i.
- // TODO(arv): Use an inner let binding once available.
- (function(i) {
- return function(x) {
- resolutions[i] = x;
- if (--count === 0) deferred.resolve(resolutions);
- }
- })(i), reject);
- SET_PRIVATE(reject, promiseCombinedDeferredSymbol, deferred);
- ++i;
+ var nextPromise = this.resolve(value);
++count;
+ nextPromise.then(
+ CreateResolveElementFunction(i, resolutions, deferred),
+ deferred.reject);
+ SET_PRIVATE(deferred.reject, promiseCombinedDeferredSymbol, deferred);
+ ++i;
}
- if (count === 0) {
- deferred.resolve(resolutions);
+ // 6.d
+ if (--count === 0) {
+ var valuesArray = [];
+ %MoveArrayContents(resolutions, valuesArray);
+ %_Call(deferred.resolve, UNDEFINED, valuesArray);
}
} catch (e) {
- deferred.reject(e)
+ %_Call(deferred.reject, UNDEFINED, e);
}
return deferred.promise;
}
« no previous file with comments | « no previous file | test/test262/test262.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698