Commit 00d5aaed authored by Stefan Penner's avatar Stefan Penner

promise.resolve(promise) === fulfillment

parent 46bce2f6
...@@ -369,7 +369,13 @@ define("rsvp/promise", ...@@ -369,7 +369,13 @@ define("rsvp/promise",
var config = __dependency1__.config; var config = __dependency1__.config;
var EventTarget = __dependency2__.EventTarget; var EventTarget = __dependency2__.EventTarget;
var noop = function() {}; function objectOrFunction(x) {
return isFunction(x) || (typeof x === "object" && x !== null);
}
function isFunction(x){
return typeof x === "function";
}
var Promise = function(resolver) { var Promise = function(resolver) {
var promise = this, var promise = this,
...@@ -407,7 +413,7 @@ define("rsvp/promise", ...@@ -407,7 +413,7 @@ define("rsvp/promise",
}; };
var invokeCallback = function(type, promise, callback, event) { var invokeCallback = function(type, promise, callback, event) {
var hasCallback = typeof callback === 'function', var hasCallback = isFunction(callback),
value, error, succeeded, failed; value, error, succeeded, failed;
if (hasCallback) { if (hasCallback) {
...@@ -423,7 +429,7 @@ define("rsvp/promise", ...@@ -423,7 +429,7 @@ define("rsvp/promise",
succeeded = true; succeeded = true;
} }
if (value && typeof value.then === 'function') { if (objectOrFunction(value) && isFunction(value.then)) {
value.then(function(value) { value.then(function(value) {
resolve(promise, value); resolve(promise, value);
}, function(error) { }, function(error) {
...@@ -473,7 +479,9 @@ define("rsvp/promise", ...@@ -473,7 +479,9 @@ define("rsvp/promise",
EventTarget.mixin(Promise.prototype); EventTarget.mixin(Promise.prototype);
function resolve(promise, value) { function resolve(promise, value) {
if (value && typeof value.then === 'function') { if (value && (value === promise) || (objectOrFunction(value) && isFunction(value.promise) && value.promise() === promise)) {
fulfill(promise, value);
} else if (objectOrFunction(value) && isFunction(value.then)) {
value.then(function(val) { value.then(function(val) {
resolve(promise, val); resolve(promise, val);
}, function(val) { }, function(val) {
......
This diff is collapsed.
...@@ -5,7 +5,13 @@ define( ...@@ -5,7 +5,13 @@ define(
var config = __dependency1__.config; var config = __dependency1__.config;
var EventTarget = __dependency2__.EventTarget; var EventTarget = __dependency2__.EventTarget;
var noop = function() {}; function objectOrFunction(x) {
return isFunction(x) || (typeof x === "object" && x !== null);
}
function isFunction(x){
return typeof x === "function";
}
var Promise = function(resolver) { var Promise = function(resolver) {
var promise = this, var promise = this,
...@@ -43,7 +49,7 @@ define( ...@@ -43,7 +49,7 @@ define(
}; };
var invokeCallback = function(type, promise, callback, event) { var invokeCallback = function(type, promise, callback, event) {
var hasCallback = typeof callback === 'function', var hasCallback = isFunction(callback),
value, error, succeeded, failed; value, error, succeeded, failed;
if (hasCallback) { if (hasCallback) {
...@@ -59,7 +65,7 @@ define( ...@@ -59,7 +65,7 @@ define(
succeeded = true; succeeded = true;
} }
if (value && typeof value.then === 'function') { if (objectOrFunction(value) && isFunction(value.then)) {
value.then(function(value) { value.then(function(value) {
resolve(promise, value); resolve(promise, value);
}, function(error) { }, function(error) {
...@@ -109,7 +115,9 @@ define( ...@@ -109,7 +115,9 @@ define(
EventTarget.mixin(Promise.prototype); EventTarget.mixin(Promise.prototype);
function resolve(promise, value) { function resolve(promise, value) {
if (value && typeof value.then === 'function') { if (value && (value === promise) || (objectOrFunction(value) && isFunction(value.promise) && value.promise() === promise)) {
fulfill(promise, value);
} else if (objectOrFunction(value) && isFunction(value.then)) {
value.then(function(val) { value.then(function(val) {
resolve(promise, val); resolve(promise, val);
}, function(val) { }, function(val) {
......
import { config } from "rsvp/config"; import { config } from "rsvp/config";
import { EventTarget } from "rsvp/events"; import { EventTarget } from "rsvp/events";
function objectOrFunction(x) {
return isFunction(x) || (typeof x === "object" && x !== null);
}
function isFunction(x){
return typeof x === "function";
}
var Promise = function(resolver) { var Promise = function(resolver) {
var promise = this, var promise = this,
resolved = false; resolved = false;
...@@ -37,7 +45,7 @@ var Promise = function(resolver) { ...@@ -37,7 +45,7 @@ var Promise = function(resolver) {
}; };
var invokeCallback = function(type, promise, callback, event) { var invokeCallback = function(type, promise, callback, event) {
var hasCallback = typeof callback === 'function', var hasCallback = isFunction(callback),
value, error, succeeded, failed; value, error, succeeded, failed;
if (hasCallback) { if (hasCallback) {
...@@ -53,7 +61,7 @@ var invokeCallback = function(type, promise, callback, event) { ...@@ -53,7 +61,7 @@ var invokeCallback = function(type, promise, callback, event) {
succeeded = true; succeeded = true;
} }
if (value && typeof value.then === 'function') { if (objectOrFunction(value) && isFunction(value.then)) {
value.then(function(value) { value.then(function(value) {
resolve(promise, value); resolve(promise, value);
}, function(error) { }, function(error) {
...@@ -103,7 +111,9 @@ Promise.prototype = { ...@@ -103,7 +111,9 @@ Promise.prototype = {
EventTarget.mixin(Promise.prototype); EventTarget.mixin(Promise.prototype);
function resolve(promise, value) { function resolve(promise, value) {
if (value && typeof value.then === 'function') { if (value && (value === promise) || (objectOrFunction(value) && isFunction(value.promise) && value.promise() === promise)) {
fulfill(promise, value);
} else if (objectOrFunction(value) && isFunction(value.then)) {
value.then(function(val) { value.then(function(val) {
resolve(promise, val); resolve(promise, val);
}, function(val) { }, function(val) {
......
/*global RSVP, describe, specify, it, assert */ /*global RSVP, describe, specify, it, assert */
describe("RSVP extensions", function() { describe("RSVP extensions", function() {
describe("self fulfillment", function(){
it("treats self fulfillment as the recursive base case", function(done){
var aDefer = new RSVP.defer(),
bDefer = new RSVP.defer();
aDefer.promise.then(function(a){
setTimeout(function(){
bDefer.resolve(bDefer);
}, 1);
return bDefer.promise;
});
bDefer.promise.then(function(c){
done();
})
aDefer.resolve(aDefer.promise);
});
});
describe("Promise constructor", function() { describe("Promise constructor", function() {
it('should exist and have length 1', function() { it('should exist and have length 1', function() {
assert(RSVP.Promise); assert(RSVP.Promise);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment