Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Give up on weak maps #602

Open
wants to merge 1 commit into
base: v2
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 15 additions & 28 deletions q.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@ var WeakMap = require("weak-map");
var iterate = require("pop-iterate");
var asap = require("asap");

var typeOfObject = "object";
function isObject(value) {
return value === Object(value);
return value !== null && typeof value === typeOfObject;
}

// long stack traces
Expand All @@ -63,7 +64,7 @@ function makeStackTraceLong(error, promise) {
error.stack.indexOf(STACK_JUMP_SEPARATOR) === -1
) {
var stacks = [];
for (var p = promise; !!p && handlers.get(p); p = handlers.get(p).became) {
for (var p = promise; p instanceof Promise && p._handler; p = p._handler.became) {
if (p.stack) {
stacks.unshift(p.stack);
}
Expand Down Expand Up @@ -178,33 +179,22 @@ function deprecate(callback, name, alternative) {

// end of long stack traces

var handlers = new WeakMap();

// When a deferred promise is forwarded to another promise, the old handler
// becomes the new handler and all messages past and present flow to the next
// handler.
function Q_getHandler(promise) {
var handler = handlers.get(promise);
if (!handler || !handler.became) {
return handler;
var handler = promise._handler;
while (handler && handler.became) {
handler = handler.became;
}
handler = follow(handler);
handlers.set(promise, handler);
promise._handler = handler;
return handler;
}

function follow(handler) {
if (!handler.became) {
return handler;
} else {
handler.became = follow(handler.became);
return handler.became;
}
}

var theViciousCycleError = new Error("Can't resolve a promise with itself");
var theViciousCycleRejection = Q_reject(theViciousCycleError);
var theViciousCycle = Q_getHandler(theViciousCycleRejection);

var thenables = new WeakMap();

/**
* Coerces a value to a promise. If the value is a promise, pass it through
* unaltered. If the value has a `then` method, it is presumed to be a promise
Expand All @@ -223,10 +213,7 @@ function Q(value) {
if (Q_isPromise(value)) {
return value;
} else if (isThenable(value)) {
if (!thenables.has(value)) {
thenables.set(value, new Promise(new Thenable(value)));
}
return thenables.get(value);
return new Promise(new Thenable(value));
} else {
return new Promise(new Fulfilled(value));
}
Expand Down Expand Up @@ -329,7 +316,7 @@ function Q_all(questions) {
} else {
++countDown;
promise = Q(promise);
promise.then(
promise.done(
function Q_all_eachFulfilled(value) {
answers[index] = value;
if (--countDown === 0) {
Expand Down Expand Up @@ -630,7 +617,7 @@ function Promise(handler) {
deferred.reject(error);
}
}
handlers.set(this, handler);
this._handler = handler;
}

/**
Expand Down Expand Up @@ -677,7 +664,7 @@ Promise.reject = Q_reject;
*/
Q.isPromise = Q_isPromise;
function Q_isPromise(object) {
return isObject(object) && !!handlers.get(object);
return isObject(object) && object instanceof Promise;
}

/**
Expand Down Expand Up @@ -1358,7 +1345,7 @@ Pending.prototype.become = function Pending_become(promise) {
var handler = Q_getHandler(promise);
this.became = handler;

handlers.set(promise, handler);
promise._handler = handler;
this.promise = void 0;

this.messages.forEach(function Pending_become_eachMessage(message) {
Expand Down