Skip to content

Commit 19bfb2a

Browse files
author
Forbes Lindesay
committed
Factor out some more try/catch statments
Also add comments
1 parent ed9c619 commit 19bfb2a

File tree

1 file changed

+53
-30
lines changed

1 file changed

+53
-30
lines changed

src/core.js

Lines changed: 53 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,47 @@ var asap = require('asap/raw')
44

55
function noop() {};
66

7-
var thenError = null;
7+
// States:
8+
//
9+
// 0 - pending
10+
// 1 - fulfilled with _value
11+
// 2 - rejected with _value
12+
// 3 - adopted the state of another promise, _value
13+
//
14+
// once the state is no longer pending (0) it is immutable
15+
16+
// All `_` prefixed properties will be reduced to `_{random number}`
17+
// at build time to obfuscate them and discourage their use.
18+
// We don't use symbols or Object.defineProperty to fully hide them
19+
// because the performance isn't good enough.
20+
21+
22+
// to avoid using try/catch inside critical functions, we
23+
// extract them to here.
24+
var LAST_ERROR = null;
825
var IS_ERROR = {};
926
function getThen(obj) {
1027
try {
1128
return obj.then;
1229
} catch (ex) {
13-
thenError = ex;
30+
LAST_ERROR = ex;
31+
return IS_ERROR;
32+
}
33+
}
34+
35+
function tryCallOne(fn, a) {
36+
try {
37+
return fn(a);
38+
} catch (ex) {
39+
LAST_ERROR = ex;
40+
return IS_ERROR;
41+
}
42+
}
43+
function tryCallTwo(fn, a, b) {
44+
try {
45+
fn(a, b);
46+
} catch (ex) {
47+
LAST_ERROR = ex;
1448
return IS_ERROR;
1549
}
1650
}
@@ -53,18 +87,15 @@ Promise.prototype._handle = function(deferred) {
5387
asap(function() {
5488
var cb = state === 1 ? deferred.onFulfilled : deferred.onRejected
5589
if (cb === null) {
56-
(state === 1 ? deferred.resolve(value) : deferred.reject(value))
90+
(state === 1 ? deferred.promise._resolve(value) : deferred.promise._reject(value))
5791
return
5892
}
59-
var ret
60-
try {
61-
ret = cb(value)
62-
}
63-
catch (e) {
64-
deferred.reject(e)
65-
return
93+
var ret = tryCallOne(cb, value);
94+
if (ret === IS_ERROR) {
95+
deferred.promise._reject(LAST_ERROR)
96+
} else {
97+
deferred.promise._resolve(ret)
6698
}
67-
deferred.resolve(ret)
6899
});
69100
};
70101
Promise.prototype._resolve = function(newValue) {
@@ -75,7 +106,7 @@ Promise.prototype._resolve = function(newValue) {
75106
if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {
76107
var then = getThen(newValue);
77108
if (then === IS_ERROR) {
78-
return this._reject(thenError);
109+
return this._reject(LAST_ERROR);
79110
}
80111
if (
81112
then === this.then &&
@@ -115,12 +146,6 @@ function Handler(onFulfilled, onRejected, promise){
115146
this.onRejected = typeof onRejected === 'function' ? onRejected : null
116147
this.promise = promise;
117148
}
118-
Handler.prototype.resolve = function (value) {
119-
this.promise._resolve(value);
120-
};
121-
Handler.prototype.reject = function (value) {
122-
this.promise._reject(value);
123-
}
124149

125150
/**
126151
* Take a potentially misbehaving resolver function and make sure
@@ -130,19 +155,17 @@ Handler.prototype.reject = function (value) {
130155
*/
131156
function doResolve(fn, promise) {
132157
var done = false;
133-
try {
134-
fn(function (value) {
135-
if (done) return
136-
done = true
137-
promise._resolve(value)
138-
}, function (reason) {
139-
if (done) return
140-
done = true
141-
promise._reject(reason)
142-
})
143-
} catch (ex) {
158+
var res = tryCallTwo(fn, function (value) {
144159
if (done) return
145160
done = true
146-
promise._reject(ex)
161+
promise._resolve(value)
162+
}, function (reason) {
163+
if (done) return
164+
done = true
165+
promise._reject(reason)
166+
})
167+
if (!done && res === IS_ERROR) {
168+
done = true
169+
promise._reject(LAST_ERROR)
147170
}
148171
}

0 commit comments

Comments
 (0)