@@ -39,51 +39,55 @@ Promise.prototype.then = function(onResolved, onRejected) {
3939 var promise2
4040
4141 // 根据标准,如果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+ }
4455
45- if ( self . status === ' resolved' ) {
56+ if ( self . status === " resolved" ) {
4657 // 如果promise1(此处即为this/self)的状态已经确定并且是resolved,我们调用onResolved
4758 // 因为考虑到有可能throw,所以我们将其包在try/catch块里
48- return promise2 = new Promise ( function ( resolve , reject ) {
59+ return ( promise2 = new Promise ( function ( resolve , reject ) {
4960 try {
5061 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 )
5563 } catch ( e ) {
5664 reject ( e ) // 如果出错,以捕获到的错误做为promise2的结果
5765 }
58- } )
66+ } ) )
5967 }
6068
6169 // 此处与前一个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 ) {
6472 try {
6573 var x = onRejected ( self . data )
66- if ( x instanceof Promise ) {
67- return x . then ( resolve , reject )
68- }
74+ resolvePromise ( promise2 , x , resolve , reject )
6975 } catch ( e ) {
7076 reject ( e )
7177 }
72- } )
78+ } ) )
7379 }
7480
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 ) {
8187 self . onResolvedCallback . push ( function ( value ) {
8288 try {
8389 var x = onResolved ( self . data )
84- if ( x instanceof Promise ) {
85- return x . then ( resolve , reject )
86- }
90+ resolvePromise ( promise2 , x , resolve , reject )
8791 } catch ( e ) {
8892 reject ( e )
8993 }
@@ -92,28 +96,107 @@ Promise.prototype.then = function(onResolved, onRejected) {
9296 self . onRejectedCallback . push ( function ( reason ) {
9397 try {
9498 var x = onRejected ( self . data )
95- if ( x instanceof Promise ) {
96- return x . then ( resolve , reject )
97- }
99+ resolvePromise ( promise2 , x , resolve , reject )
98100 } catch ( e ) {
99101 reject ( e )
100102 }
101103 } )
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 )
103182 }
104183}
105184
106185var a = new Promise ( resolve => {
107- resolve ( 1 )
186+ setTimeout ( ( ) => {
187+ resolve ( 1 )
188+ } , 500 )
108189} )
109190 . then ( res => {
110- console . log ( res )
191+ console . log ( "res1" , res )
111192 return new Promise ( r => {
112- setTimeout ( ( ) => {
113- r ( 15 )
114- } , 1000 )
193+ r (
194+ new Promise ( r1 => {
195+ r1 ( 15 )
196+ } ) ,
197+ )
115198 } )
116199 } )
117200 . then ( res => {
118- console . log ( "res " , res )
201+ console . log ( "res2 " , res )
119202 } )
0 commit comments