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

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: Created 5 years 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 | no next file » | 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 de9597942c010f52d6dd996fc5faac2000b628ec..025a5069ed38e00a3df3663ff01b3900dff5667c 100644
--- a/src/js/promise.js
+++ b/src/js/promise.js
@@ -69,13 +69,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);
+ callbacks.reject(e);
Dan Ehrenberg 2016/01/04 02:49:15 I think this needs to be %_Call(callbacks.reject,
} finally {
%DebugPopPromise();
}
@@ -204,11 +204,11 @@ function PromiseResolve(promise, x) {
if (IS_CALLABLE(then)) {
// PromiseResolveThenableJob
return %EnqueueMicrotask(function() {
+ var callbacks = CreateResolvingFunctions(promise);
try {
- var callbacks = CreateResolvingFunctions(promise);
%_Call(then, x, callbacks.resolve, callbacks.reject);
} catch (e) {
- PromiseReject(promise, e);
+ callbacks.reject(promise, e);
Dan Ehrenberg 2016/01/04 02:49:15 Here too
}
});
}
@@ -362,28 +362,28 @@ function PromiseCast(x) {
}
function PromiseAll(iterable) {
+ if (!IS_RECEIVER(this)) {
+ throw MakeTypeError(kCalledOnNonObject, "Promise.all");
+ }
+
var deferred = NewPromiseCapability(this);
var resolutions = [];
try {
- var count = 0;
+ var count = 1;
var i = 0;
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;
+ resolutions[i] = UNDEFINED;
+ var nextPromise = this.resolve(value);
++count;
+ nextPromise.then(
+ CreateResolveElementFunction(i, resolutions, deferred),
+ deferred.reject);
+ SET_PRIVATE(deferred.reject, promiseCombinedDeferredSymbol, deferred);
+ ++i;
}
- if (count === 0) {
+ // 6.d
+ if (--count === 0) {
deferred.resolve(resolutions);
}
@@ -391,6 +391,16 @@ function PromiseAll(iterable) {
deferred.reject(e)
}
return deferred.promise;
+
+ function CreateResolveElementFunction(index, values, promiseCapability) {
+ var alreadyCalled = false;
+ return function(x) {
+ if (alreadyCalled === true) return;
+ alreadyCalled = true;
+ values[index] = x;
+ if (--count === 0) promiseCapability.resolve(values);
+ };
+ }
}
function PromiseRace(iterable) {
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698