Appearance
当成功或失败回调返回promsie时 1
本节目标:理解“当成功或失败回调返回promsie时 1”的核心思路,并能把它用于实际开发或面试表达。 当我们的
promise状态凝固后,我们要执行我们通过then(第一个then)添加的成功或失败回调;
这时,如果第一个then添加的成功或失败的回调函数返回的一个promise,即一个异步代码,如果此时我们给第一个then回调返回的P又添加了then成功和失败回调的话,那这个第二个then中的回调函数自然要等待第一个then返回的P的状态凝固才行,即要调用第一个then中的promise2的resolve和reject方法才行;
现在第一个then的回调函数是异步的,那我们要等,等回调函数有结果了,我们调用第一个then中p的resolve和reject方法,把结果传出去;这样,第二个then中的回调才会在第一个then的状态凝固后,才会执行;
什么时候调用第一个then中promise2的resolve和reject方法呢? 这是老一套,即然回调函数的执行结果是一个p,那我们就可以在内部加上then成功和失败回调,而这个内部的成功和失败的回调函数,就是我们第一个then中promise2的凝固状态触发回调的resolve和reject方法;
这样的话,当第一个then的成功或失败回调中返回的P有状态凝固时,我们在内部添加的成功和失败回调就会执行,也就是调用第一个then的中promise2的凝固状态的方法resolve和reject ,这样第一个then中创建的promise2状态凝固了,那我们第二个then添加的成功和失败回调就会执行了,代码可以继续链式调用;
if
(this.state===
FULFILLED){try {let x =
onResolve(this.value); `if`
(typeofx === 'object' && typeof x !== null || typeof x ===
'function'){// 加try catch 防止取属性时触发的get函数报错 try {const then =
x.then; `if`
(typeofthen ===
'function'){// 认定为promise对象,则添加成功和失败回调,等待promise异步代码结束,状态凝固 // 用call而不是x.then是因为如果then方法是通过defineProperty来定义的; // 会再次调用get方法
then.call(x,resolve,reject); `}` `else` `{`
`//` `then`不是函数直接`resolve`成功值
resolve(x) `}`
`}` `catch`
(e){// 抛出错误
reject(e) `}`
`}` `else`
{//普通对象
resolve(x) `}`
resolve(x)} catch
(e){
reject(e);}
}封装resolvePromise方法:
const PENDING =
'PENDING';
constFULFILLED =
'FUFILLED';
constREJECTED =
'REJECTED';
constresolvePromise =
(x,resolve,reject)=\> {if
(typeofx === 'object' && typeof x !== null || typeof x ===
'function'){// 加try catch 防止取属性时触发的get函数报错 try {const then =
x.then; `if`
(typeofthen ===
'function'){// 认定为promise对象,则添加成功和失败回调,等待promise异步代码结束,状态凝固 // 用call而不是x.then是因为如果then方法是通过defineProperty来定义的; // 会再次调用get方法
then.call(x,resolve,reject); `}` `else` `{`
`//` `then`不是函数直接`resolve`成功值
resolve(x) `}`
`}` `catch`
(e){// 抛出错误
reject(e) `}`
} else
{//普通对象
resolve(x)}
}
classMyPromise {
constructor(excutor){
this.state=
PENDING;this.value=
undefined;this.reason=
undefined;this.resolveCallbacks= [];
this.rejectedCallbacks= [];const resolve =
(value)=\> {if
(this.valueinstanceof
MyPromise){return
this.value.then(resolve,reject) `}`
`if`
(this.state===
PENDING){
this.state=
FULFILLED;this.value=
value;this.resolveCallbacks.forEach(fn=\>
fn()); `}`
`}`
`const` `reject` `=`
(reason)=\> {if
(this.state===
PENDING){
this.state=
REJECTED;this.reason=
reason;this.rejectedCallbacks.forEach(fn=\>
fn()); `}`
`}`
`try` `{`
excutor(resolve,resolve) `}` `catch`
(e){
reject(e); `}`
}
then(onResolve,onReject){const promise2 = new
Promise((resolve,reject)=\> {if
(this.state===
FULFILLED){try {let x =
onResolve(this.value);resolvePromise(x,resolve,reject) `}` `catch`
(e){
reject(e); `}`
`}`
`if`
(this.state===
REJECTED){try {let x =
onReject(this.value);resolvePromise(x,resolve,reject); `}` `catch`
(e){
reject(e) `}`
`}`
`if`
(this.state===
PENDING){
this.resolveCallbacks.push(()=\> {try {let x =
onResolve(this.value);resolvePromise(x,resolve,reject) `}` `catch`
(e){
reject(e) `}`
`})`
this.rejectedCallbacks.push(()=\> {try {let x =
onReject(this.value);resolvePromise(x,resolve,reject) `}` `catch`
(e){
reject(e) `}`
`})`
`}`
`})`
`return`
promise2;}
}