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

Unified Diff: src/promise.js

Issue 99573002: Promises: some adaptations to spec (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 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
Index: src/promise.js
diff --git a/src/promise.js b/src/promise.js
index 30f4f07b4b7b21c1c83b0c6e590eeb8f4c2803d6..e0c6a0b8afa8d6ee66c3ce7ec802b7708e638d4d 100644
--- a/src/promise.js
+++ b/src/promise.js
@@ -62,11 +62,14 @@ function IsPromise(x) {
function Promise(resolver) {
if (resolver === promiseRaw) return;
+ if (!%_IsConstructCall()) throw MakeTypeError('not_a_promise', [this]);
var promise = PromiseInit(this);
- resolver(function(x) { PromiseResolve(promise, x) },
- function(r) { PromiseReject(promise, r) });
- // TODO(rossberg): current draft makes exception from this call asynchronous,
- // but that's probably a mistake.
+ try {
+ resolver(function(x) { PromiseResolve(promise, x) },
+ function(r) { PromiseReject(promise, r) });
+ } catch (e) {
+ PromiseReject(promise, e);
+ }
}
function PromiseSet(promise, status, value, onResolve, onReject) {
@@ -82,9 +85,10 @@ function PromiseInit(promise) {
}
function PromiseDone(promise, status, value, promiseQueue) {
- if (GET_PRIVATE(promise, promiseStatus) !== 0) return;
- PromiseEnqueue(value, GET_PRIVATE(promise, promiseQueue));
- PromiseSet(promise, status, value);
+ if (GET_PRIVATE(promise, promiseStatus) === 0) {
+ PromiseEnqueue(value, GET_PRIVATE(promise, promiseQueue));
+ PromiseSet(promise, status, value);
+ }
}
function PromiseResolve(promise, x) {
@@ -222,11 +226,12 @@ function PromiseCoerce(constructor, x) {
var then;
if (IsPromise(x)) {
return x;
- } else if (!IS_NULL_OR_UNDEFINED(x) && %IsCallable(then = x.then)) {
+ } else if (!IS_NULL_OR_UNDEFINED(x) &&
+ typeof (then = x.then) === 'function') {
Dmitry Lomov (no reviews) 2013/12/04 09:24:43 Can we not have assignments in conditions? Pretty
rossberg 2013/12/06 11:43:29 Done.
if (PromiseCoerce.table.has(x)) {
return PromiseCoerce.table.get(x);
} else {
- var deferred = constructor.deferred();
+ var deferred = %_CallFunction(constructor, PromiseDeferred);
PromiseCoerce.table.set(x, deferred.promise);
try {
%_CallFunction(x, deferred.resolve, deferred.reject, then);
@@ -245,39 +250,44 @@ function PromiseCoerce(constructor, x) {
function PromiseCast(x) {
// TODO(rossberg): cannot do better until we support @@create.
- return IsPromise(x) ? x : this.resolved(x);
+ return IsPromise(x) ? x : this.resolve(x);
}
function PromiseAll(values) {
- var deferred = this.deferred();
+ var deferred = %_CallFunction(this, PromiseDeferred);
Dmitry Lomov (no reviews) 2013/12/04 09:24:43 Instead of using %_CallFunction here and above, le
rossberg 2013/12/06 11:43:29 Why? Avoiding extra hoops like that is exactly why
var resolutions = [];
- var count = values.length;
- if (count === 0) {
- deferred.resolve(resolutions);
- } else {
- for (var i = 0; i < values.length; ++i) {
- this.cast(values[i]).chain(
- function(i, x) {
- resolutions[i] = x;
- if (--count === 0) deferred.resolve(resolutions);
- }.bind(UNDEFINED, i), // TODO(rossberg): use let loop once available
- function(r) {
- if (count > 0) { count = 0; deferred.reject(r) }
- }
- );
+ try {
+ var count = values.length;
+ if (count === 0) {
+ deferred.resolve(resolutions);
+ } else {
+ for (var i = 0; i < values.length; ++i) {
+ this.cast(values[i]).chain(
+ function(i, x) {
+ resolutions[i] = x;
+ if (--count === 0) deferred.resolve(resolutions);
+ }.bind(UNDEFINED, i), // TODO(rossberg): use let loop once available
+ function(r) { deferred.reject(r) }
Dmitry Lomov (no reviews) 2013/12/04 09:24:43 Why 'count > 0' condition disappeared here? What i
rossberg 2013/12/06 11:43:29 Reject used to throw on non-pending promises in an
+ );
+ }
}
+ } catch (e) {
+ deferred.reject(e)
}
return deferred.promise;
}
function PromiseOne(values) { // a.k.a. race
- var deferred = this.deferred();
- var done = false;
- for (var i = 0; i < values.length; ++i) {
- this.cast(values[i]).chain(
- function(x) { if (!done) { done = true; deferred.resolve(x) } },
- function(r) { if (!done) { done = true; deferred.reject(r) } }
- );
+ var deferred = %_CallFunction(this, PromiseDeferred);
Dmitry Lomov (no reviews) 2013/12/04 09:24:43 Ditto re: %_CallFunction
+ try {
+ for (var i = 0; i < values.length; ++i) {
+ this.cast(values[i]).chain(
+ function(x) { deferred.resolve(x) },
+ function(r) { deferred.reject(r) }
+ );
+ }
+ } catch (e) {
+ deferred.reject(e)
}
return deferred.promise;
}
@@ -288,9 +298,9 @@ function SetUpPromise() {
%CheckIsBootstrapping()
global.Promise = $Promise;
InstallFunctions($Promise, DONT_ENUM, [
- "deferred", PromiseDeferred,
- "resolved", PromiseResolved,
- "rejected", PromiseRejected,
+ "defer", PromiseDeferred,
Dmitry Lomov (no reviews) 2013/12/04 09:24:43 So, my understanding is that 'defer' is non-standa
rossberg 2013/12/06 11:43:29 As per off-line discussion, I leave it in for the
+ "resolve", PromiseResolved,
+ "reject", PromiseRejected,
"all", PromiseAll,
"one", PromiseOne,
"cast", PromiseCast
« no previous file with comments | « src/messages.js ('k') | src/runtime.h » ('j') | test/mjsunit/harmony/promises.js » ('J')

Powered by Google App Engine
This is Rietveld 408576698