@@ -39,51 +39,55 @@ Promise.prototype.then = function(onResolved, onRejected) {
39
39
var promise2
40
40
41
41
// 根据标准,如果then的参数不是function,则我们需要忽略它,此处以如下方式处理
42
- onResolved = typeof onResolved === 'function' ? onResolved : function ( value ) { }
43
- onRejected = typeof onRejected === 'function' ? onRejected : function ( reason ) { }
42
+ // 并且默认函数需要return值 以便于空值的穿透
43
+ onResolved =
44
+ typeof onResolved === "function"
45
+ ? onResolved
46
+ : function ( value ) {
47
+ return value
48
+ }
49
+ onRejected =
50
+ typeof onRejected === "function"
51
+ ? onRejected
52
+ : function ( reason ) {
53
+ return reason
54
+ }
44
55
45
- if ( self . status === ' resolved' ) {
56
+ if ( self . status === " resolved" ) {
46
57
// 如果promise1(此处即为this/self)的状态已经确定并且是resolved,我们调用onResolved
47
58
// 因为考虑到有可能throw,所以我们将其包在try/catch块里
48
- return promise2 = new Promise ( function ( resolve , reject ) {
59
+ return ( promise2 = new Promise ( function ( resolve , reject ) {
49
60
try {
50
61
var x = onResolved ( self . data )
51
- if ( x instanceof Promise ) { // 如果onResolved的返回值是一个Promise对象,直接取它的结果做为promise2的结果
52
- return x . then ( resolve , reject )
53
- }
54
- resolve ( x ) // 否则,以它的返回值做为promise2的结果
62
+ resolvePromise ( promise2 , x , resolve , reject )
55
63
} catch ( e ) {
56
64
reject ( e ) // 如果出错,以捕获到的错误做为promise2的结果
57
65
}
58
- } )
66
+ } ) )
59
67
}
60
68
61
69
// 此处与前一个if块的逻辑几乎相同,区别在于所调用的是onRejected函数,就不再做过多解释
62
- if ( self . status === ' rejected' ) {
63
- return promise2 = new Promise ( function ( resolve , reject ) {
70
+ if ( self . status === " rejected" ) {
71
+ return ( promise2 = new Promise ( function ( resolve , reject ) {
64
72
try {
65
73
var x = onRejected ( self . data )
66
- if ( x instanceof Promise ) {
67
- return x . then ( resolve , reject )
68
- }
74
+ resolvePromise ( promise2 , x , resolve , reject )
69
75
} catch ( e ) {
70
76
reject ( e )
71
77
}
72
- } )
78
+ } ) )
73
79
}
74
80
75
- if ( self . status === ' pending' ) {
76
- // 如果当前的Promise还处于pending状态,我们并不能确定调用onResolved还是onRejected,
77
- // 只能等到Promise的状态确定后,才能确实如何处理。
78
- // 所以我们需要把我们的**两种情况**的处理逻辑做为callback放入promise1(此处即this/self)的回调数组里
79
- // 逻辑本身跟第一个if块内的几乎一致,此处不做过多解释
80
- return promise2 = new Promise ( function ( resolve , reject ) {
81
+ if ( self . status === " pending" ) {
82
+ // 如果当前的Promise还处于pending状态,我们并不能确定调用onResolved还是onRejected,
83
+ // 只能等到Promise的状态确定后,才能确实如何处理。
84
+ // 所以我们需要把我们的**两种情况**的处理逻辑做为callback放入promise1(此处即this/self)的回调数组里
85
+ // 逻辑本身跟第一个if块内的几乎一致,此处不做过多解释
86
+ return ( promise2 = new Promise ( function ( resolve , reject ) {
81
87
self . onResolvedCallback . push ( function ( value ) {
82
88
try {
83
89
var x = onResolved ( self . data )
84
- if ( x instanceof Promise ) {
85
- return x . then ( resolve , reject )
86
- }
90
+ resolvePromise ( promise2 , x , resolve , reject )
87
91
} catch ( e ) {
88
92
reject ( e )
89
93
}
@@ -92,28 +96,107 @@ Promise.prototype.then = function(onResolved, onRejected) {
92
96
self . onRejectedCallback . push ( function ( reason ) {
93
97
try {
94
98
var x = onRejected ( self . data )
95
- if ( x instanceof Promise ) {
96
- return x . then ( resolve , reject )
97
- }
99
+ resolvePromise ( promise2 , x , resolve , reject )
98
100
} catch ( e ) {
99
101
reject ( e )
100
102
}
101
103
} )
102
- } )
104
+ } ) )
105
+ }
106
+ }
107
+
108
+ /*
109
+ resolvePromise函数即为根据x的值来决定promise2的状态的函数
110
+ 也即标准中的[Promise Resolution Procedure](https://promisesaplus.com/#point-47)
111
+ x为`promise2 = promise1.then(onResolved, onRejected)`里`onResolved/onRejected`的返回值
112
+ `resolve`和`reject`实际上是`promise2`的`executor`的两个实参,因为很难挂在其它的地方,所以一并传进来。
113
+ 相信各位一定可以对照标准把标准转换成代码,这里就只标出代码在标准中对应的位置,只在必要的地方做一些解释
114
+ */
115
+ function resolvePromise ( promise2 , x , resolve , reject ) {
116
+ var then
117
+ var thenCalledOrThrow = false
118
+
119
+ // 对应标准2.3.1节
120
+ // If promise and x refer to the same object, reject promise with a TypeError as the reason.
121
+ if ( promise2 === x ) {
122
+ return reject ( new TypeError ( "Chaining cycle detected for promise!" ) )
123
+ }
124
+
125
+ // 2.3.2
126
+ /**
127
+ * If x is a promise, adopt its state [3.4]:
128
+ If x is pending, promise must remain pending until x is fulfilled or rejected.
129
+ If/when x is fulfilled, fulfill promise with the same value.
130
+ If/when x is rejected, reject promise with the same reason.
131
+ */
132
+
133
+ if ( x instanceof Promise ) {
134
+ // 对应标准2.3.2节
135
+ // 如果x的状态还没有确定,那么它是有可能被一个thenable决定最终状态和值的 有可能x是个promise但是它resolve的又是一个promise
136
+ // 比如
137
+ // 所以这里需要做一下处理,而不能一概的以为它会被一个“正常”的值resolve
138
+ if ( x . status === "pending" ) {
139
+ x . then ( function ( value ) {
140
+ resolvePromise ( promise2 , value , resolve , reject )
141
+ } , reject )
142
+ } else {
143
+ // 但如果这个Promise的状态已经确定了,那么它肯定有一个“正常”的值,而不是一个thenable,所以这里直接取它的状态
144
+ x . then ( resolve , reject )
145
+ }
146
+ return
147
+ }
148
+
149
+ if ( x !== null && ( typeof x === "object" || typeof x === "function" ) ) {
150
+ // 2.3.3
151
+ try {
152
+ // 2.3.3.1 因为x.then有可能是一个getter,这种情况下多次读取就有可能产生副作用
153
+ // 即要判断它的类型,又要调用它,这就是两次读取
154
+ then = x . then
155
+
156
+ if ( typeof then === "function" ) {
157
+ // 2.3.3.3
158
+ then . call (
159
+ x ,
160
+ function rs ( y ) {
161
+ // 2.3.3.3.1
162
+ if ( thenCalledOrThrow ) return
163
+ thenCalledOrThrow = true
164
+ return resolvePromise ( promise2 , y , resolve , reject ) // 2.3.3.3.1
165
+ } ,
166
+ function rj ( r ) {
167
+ if ( thenCalledOrThrow ) return // 2.3.3.3.3 即这三处谁选执行就以谁的结果为准
168
+ thenCalledOrThrow = true
169
+ return reject ( r )
170
+ } ,
171
+ )
172
+ } else {
173
+ resolve ( x )
174
+ }
175
+ } catch ( e ) {
176
+ if ( thenCalledOrThrow ) return // 2.3.3.3.3 即这三处谁选执行就以谁的结果为准
177
+ thenCalledOrThrow = true
178
+ return reject ( e )
179
+ }
180
+ } else {
181
+ resolve ( x )
103
182
}
104
183
}
105
184
106
185
var a = new Promise ( resolve => {
107
- resolve ( 1 )
186
+ setTimeout ( ( ) => {
187
+ resolve ( 1 )
188
+ } , 500 )
108
189
} )
109
190
. then ( res => {
110
- console . log ( res )
191
+ console . log ( "res1" , res )
111
192
return new Promise ( r => {
112
- setTimeout ( ( ) => {
113
- r ( 15 )
114
- } , 1000 )
193
+ r (
194
+ new Promise ( r1 => {
195
+ r1 ( 15 )
196
+ } ) ,
197
+ )
115
198
} )
116
199
} )
117
200
. then ( res => {
118
- console . log ( "res " , res )
201
+ console . log ( "res2 " , res )
119
202
} )
0 commit comments