Browse files

Break coercion cycles with cooperating promises

Cooperating promise libraries must implement `valueOf` to extract the
fulfillment value from a fulfilled promise (or return the selfsame
promise for an unresolved or rejected promise).  This breaks cycles in
coercion, where one library uses `resolve` to coerce a foreign promise
to a local promise, which would in turn call `then` on the foreign
promise, which would in turn attempt to coerce the promise with its own
`resolve`, which would then in turn call `then` on our coerced promise,
ad nauseum.

Fixes #106.
  • Loading branch information...
1 parent b160c43 commit facbb77e6aa62ab30fe72f7536dfd456f51b01ff @kriskowal committed Aug 23, 2012
Showing with 9 additions and 0 deletions.
  1. +9 −0 q.js
9 q.js
@@ -775,6 +775,15 @@ function resolve(object) {
if (isPromise(object)) {
return object;
+ // In order to break infinite recursion or loops between `then` and
+ // `resolve`, it is necessary to attempt to extract fulfilled values
+ // out of foreign promise implementations before attempting to wrap
+ // them as unresolved promises. It is my hope that other
+ // implementations will implement `valueOf` to synchronously extract
+ // the fulfillment value from their fulfilled promises. If the
+ // other promise library does not implement `valueOf`, the
+ // implementations on primordial prototypes are harmless.
+ object = valueOf(object);
// assimilate thenables, CommonJS/Promises/A
if (object && typeof object.then === "function") {
var deferred = defer();

0 comments on commit facbb77

Please sign in to comment.