Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.

Commit 998edd7

Browse files
committed
Give up on weak maps
No more guarantees. Ten times faster.
1 parent 600dbfe commit 998edd7

File tree

1 file changed

+15
-28
lines changed

1 file changed

+15
-28
lines changed

q.js

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@ var WeakMap = require("weak-map");
4444
var iterate = require("pop-iterate");
4545
var asap = require("asap");
4646

47+
var typeOfObject = "object";
4748
function isObject(value) {
48-
return value === Object(value);
49+
return value !== null && typeof value === typeOfObject;
4950
}
5051

5152
// long stack traces
@@ -63,7 +64,7 @@ function makeStackTraceLong(error, promise) {
6364
error.stack.indexOf(STACK_JUMP_SEPARATOR) === -1
6465
) {
6566
var stacks = [];
66-
for (var p = promise; !!p && handlers.get(p); p = handlers.get(p).became) {
67+
for (var p = promise; p instanceof Promise && p._handler; p = p._handler.became) {
6768
if (p.stack) {
6869
stacks.unshift(p.stack);
6970
}
@@ -178,33 +179,22 @@ function deprecate(callback, name, alternative) {
178179

179180
// end of long stack traces
180181

181-
var handlers = new WeakMap();
182-
182+
// When a deferred promise is forwarded to another promise, the old handler
183+
// becomes the new handler and all messages past and present flow to the next
184+
// handler.
183185
function Q_getHandler(promise) {
184-
var handler = handlers.get(promise);
185-
if (!handler || !handler.became) {
186-
return handler;
186+
var handler = promise._handler;
187+
while (handler && handler.became) {
188+
handler = handler.became;
187189
}
188-
handler = follow(handler);
189-
handlers.set(promise, handler);
190+
promise._handler = handler;
190191
return handler;
191192
}
192193

193-
function follow(handler) {
194-
if (!handler.became) {
195-
return handler;
196-
} else {
197-
handler.became = follow(handler.became);
198-
return handler.became;
199-
}
200-
}
201-
202194
var theViciousCycleError = new Error("Can't resolve a promise with itself");
203195
var theViciousCycleRejection = Q_reject(theViciousCycleError);
204196
var theViciousCycle = Q_getHandler(theViciousCycleRejection);
205197

206-
var thenables = new WeakMap();
207-
208198
/**
209199
* Coerces a value to a promise. If the value is a promise, pass it through
210200
* unaltered. If the value has a `then` method, it is presumed to be a promise
@@ -223,10 +213,7 @@ function Q(value) {
223213
if (Q_isPromise(value)) {
224214
return value;
225215
} else if (isThenable(value)) {
226-
if (!thenables.has(value)) {
227-
thenables.set(value, new Promise(new Thenable(value)));
228-
}
229-
return thenables.get(value);
216+
return new Promise(new Thenable(value));
230217
} else {
231218
return new Promise(new Fulfilled(value));
232219
}
@@ -329,7 +316,7 @@ function Q_all(questions) {
329316
} else {
330317
++countDown;
331318
promise = Q(promise);
332-
promise.then(
319+
promise.done(
333320
function Q_all_eachFulfilled(value) {
334321
answers[index] = value;
335322
if (--countDown === 0) {
@@ -630,7 +617,7 @@ function Promise(handler) {
630617
deferred.reject(error);
631618
}
632619
}
633-
handlers.set(this, handler);
620+
this._handler = handler;
634621
}
635622

636623
/**
@@ -677,7 +664,7 @@ Promise.reject = Q_reject;
677664
*/
678665
Q.isPromise = Q_isPromise;
679666
function Q_isPromise(object) {
680-
return isObject(object) && !!handlers.get(object);
667+
return isObject(object) && object instanceof Promise;
681668
}
682669

683670
/**
@@ -1358,7 +1345,7 @@ Pending.prototype.become = function Pending_become(promise) {
13581345
var handler = Q_getHandler(promise);
13591346
this.became = handler;
13601347

1361-
handlers.set(promise, handler);
1348+
promise._handler = handler;
13621349
this.promise = void 0;
13631350

13641351
this.messages.forEach(function Pending_become_eachMessage(message) {

0 commit comments

Comments
 (0)