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

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: Throw on non-function resolver Created 6 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 | « src/messages.js ('k') | src/runtime.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/promise.js
diff --git a/src/promise.js b/src/promise.js
index 30f4f07b4b7b21c1c83b0c6e590eeb8f4c2803d6..2a3f4fd5cfd93f1a396bc362d3bd2a42b09d25cd 100644
--- a/src/promise.js
+++ b/src/promise.js
@@ -62,11 +62,16 @@ function IsPromise(x) {
function Promise(resolver) {
if (resolver === promiseRaw) return;
+ if (!%_IsConstructCall()) throw MakeTypeError('not_a_promise', [this]);
arv (Not doing code reviews) 2014/01/09 15:47:15 Doesn't this break sub classing? function SubProm
rossberg 2014/01/09 16:09:56 I agree, but it's what the spec says.
arv (Not doing code reviews) 2014/01/09 19:13:27 I think this is the right call for now. Once we su
+ if (typeof resolver !== 'function')
+ throw MakeTypeError('resolver_not_a_function', [resolver]);
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 +87,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) {
@@ -219,25 +225,24 @@ function PromiseThen(onResolve, onReject) {
PromiseCoerce.table = new $WeakMap;
function PromiseCoerce(constructor, x) {
- var then;
- if (IsPromise(x)) {
- return x;
- } else if (!IS_NULL_OR_UNDEFINED(x) && %IsCallable(then = x.then)) {
- if (PromiseCoerce.table.has(x)) {
- return PromiseCoerce.table.get(x);
- } else {
- var deferred = constructor.deferred();
- PromiseCoerce.table.set(x, deferred.promise);
- try {
- %_CallFunction(x, deferred.resolve, deferred.reject, then);
- } catch(e) {
- deferred.reject(e);
+ if (!(IsPromise(x) || IS_NULL_OR_UNDEFINED(x))) {
+ var then = x.then;
+ if (typeof then === 'function') {
+ if (PromiseCoerce.table.has(x)) {
+ return PromiseCoerce.table.get(x);
+ } else {
+ var deferred = %_CallFunction(constructor, PromiseDeferred);
+ PromiseCoerce.table.set(x, deferred.promise);
+ try {
+ %_CallFunction(x, deferred.resolve, deferred.reject, then);
+ } catch(e) {
+ deferred.reject(e);
+ }
+ return deferred.promise;
}
- return deferred.promise;
}
- } else {
- return x;
}
+ return x;
}
@@ -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);
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) }
+ );
+ }
}
+ } 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) } }
- );
+function PromiseOne(values) {
arv (Not doing code reviews) 2014/01/09 15:47:15 Rename this to PromiseRace to match? Why isn't th
rossberg 2014/01/09 16:09:56 Because the resolve/reject functions at some point
+ var deferred = %_CallFunction(this, PromiseDeferred);
+ 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,11 +298,11 @@ function SetUpPromise() {
%CheckIsBootstrapping()
global.Promise = $Promise;
InstallFunctions($Promise, DONT_ENUM, [
- "deferred", PromiseDeferred,
- "resolved", PromiseResolved,
- "rejected", PromiseRejected,
+ "defer", PromiseDeferred,
+ "resolve", PromiseResolved,
+ "reject", PromiseRejected,
"all", PromiseAll,
- "one", PromiseOne,
+ "race", PromiseOne,
"cast", PromiseCast
]);
InstallFunctions($Promise.prototype, DONT_ENUM, [
« no previous file with comments | « src/messages.js ('k') | src/runtime.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698