2
2
3
3
var asap = require ( 'asap' )
4
4
5
+ // Use Symbol if it's available, but otherwise just
6
+ // generate a random string as this is probably going
7
+ // to be unique
8
+ var handleSymbol = typeof Symbol === 'function' ?
9
+ Symbol ( ) :
10
+ (
11
+ '_promise_internal_key_handle_' +
12
+ Math . random ( ) . toString ( 35 ) . substr ( 2 , 10 ) + '_'
13
+ )
14
+
5
15
module . exports = Promise ;
6
16
function Promise ( fn ) {
7
17
if ( typeof this !== 'object' ) throw new TypeError ( 'Promises must be constructed via new' )
@@ -16,6 +26,7 @@ function Promise(fn) {
16
26
handle ( new Handler ( onFulfilled , onRejected , resolve , reject ) )
17
27
} )
18
28
}
29
+ this . then [ handleSymbol ] = handle ;
19
30
20
31
function handle ( deferred ) {
21
32
if ( state === null ) {
@@ -46,7 +57,18 @@ function Promise(fn) {
46
57
if ( newValue && ( typeof newValue === 'object' || typeof newValue === 'function' ) ) {
47
58
var then = newValue . then
48
59
if ( typeof then === 'function' ) {
49
- doResolve ( then . bind ( newValue ) , resolve , reject )
60
+ if ( typeof then [ handleSymbol ] === 'function' ) {
61
+ // to prevent a memory leak, we adopt the value of the other promise
62
+ // allowing this promise to be garbage collected as soon as nobody
63
+ // has a reference to it
64
+ handle = ( self [ handleSymbol ] = then [ handleSymbol ] ) ;
65
+ self . then = then ;
66
+ deferreds . forEach ( function ( deferred ) {
67
+ handle ( deferred ) ;
68
+ } ) ;
69
+ } else {
70
+ doResolve ( then . bind ( newValue ) , resolve , reject )
71
+ }
50
72
return
51
73
}
52
74
}
0 commit comments