Promise的关键问题 + 手写Promise -- 暑假Day9

Promise的几个关键问题

  • 如何改变promise的状态?
    调用resolve就是成功,调用reject就是失败,还有一个抛出异常,然后当前是pending就会改变为rejected
const p = new Promise((resolve, reject) => {
    throw new Error('出错了');
})
console.log(p);

在这里插入图片描述

  • 一个promise指定多个成功/失败回调函数,都会调用吗?
    都会调用

  • 改变promise状态和指定回调函数谁先谁后?
    都有可能,当执行器函数里面有定时器的时候,就是先指定回调函数再改变promise的状态,同理,把指定的回调函数放在定时器里面就可以正好反过来,想要先改变promise的状态还有一个简单的方法,就是将执行器函数里面的定时器删除,让他们直接进行同步执行

  • then返回的新promise的结果状态由什么决定?
    由then回调函数的返回值决定,默认返回undefined,走的是resolve

    • 若抛出异常,新的promise状态为rejected,reason就是抛出的异常
    • 若返回的是非promise的任意值,新promise变为resolved,value就是返回的值
    • 如果返回的是另一个新的promise,这个promise的结果就是新的promise的结果
  • promise如何串联多个操作任务?
    通过then的链式调用串联多个同步/异步任务,想要同步操作的话直接return,想要异步操作的话就返回promise

  • promise异常传递
    当使用promise的then的链式调用的时候,可以在最后指定失败的回调,前面任何操作出了异常,都会传到最后失败的回调中处理

  • 中断promise链
    当在链式调用的时候,如果想在中间中断,即不再调用后面的回调函数,解决办法是在回调函数中返回一个pending状态的promise对象,也就是返回一个空的promise

reason => {throw reason;}//如果不写reason默认是将reason抛出

自定义promise

// 自定义Promise函数模块:IIFE
(function (window) {
   // 常量一般用全大写来命名
   const PENDING = 'pending';
   const RESOLVED = 'resolved';
   const REJECTED = 'rejected';      
   // excutor同步执行
   function Promise(excutor) {
       const self = this;
       this.status = PENDING;
       this.data = undefined;
       this.callbacks = [];

       function resolve(value) {
           if (self.status !== PENDING) {
               return ;
           }
           self.status = RESOLVED;//修改状态
           self.data = value;//保存value

           // 如果有待执行的callback函数,立即异步执行回调
           if (self.callbacks.length > 0) {
               setTimeout(() => {//放入队列
                   self.callbacks.forEach(calobj => {
                       calobj.onResolved(value);
                   });
               }, 0)
           }
       }
       function reject(reason) {
           if (self.status !== PENDING) {
               return ;
           }
           self.status = REJECTED;//修改状态
           self.data = reason;//保存value

           // 如果有待执行的callback函数,立即异步执行回调
           if (self.callbacks.length > 0) {
               setTimeout(() => {
                   self.callbacks.forEach(calobj => {
                       calobj.onRejected(reason);
                   });
               }, 0)
           }
       }

       try{
           excutor(resolve, reject);
       }catch(error){
           reject(error);
       }
   }
   
   // then
   Promise.prototype.then = function (onResolved, onRejected) {
       onResolved = typeof onResolved === 'function' ? onResolved : value => value;
       onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw reason}//用于判断是否是异常传递
       
       const self = this;

       return new Promise((resolve, reject) => {

           function handle(callback) {
               // 三种情况,1. 抛出异常2. 返回非promise3. 返回promise
               try {
                   const result = callback(self.data);

                   if (result instanceof Promise) {
                      //  result.then(
                      //      value => resolve(value), 
                      //      reason => reject(reason)
                      //  )
                      result.then(resolve, reject);
                   }else{
                      resolve(result);
                   }
                   } catch (error) {
                       reject(error);
                   }
           }
           if (self.status === PENDING) {
               self.callbacks.push(
                   {onResolved(value) {
                       handle(onResolved);
                   },
                   onRejected(reason) {
                       handle(onRejected);
                   }}
               )
           }else if (self.status === RESOLVED) {
               setTimeout(() => {
                   handle(onResolved);
               }, 0)
           }else{
               setTimeout(() => {
                   handle(onRejected);
               }, 0)
           }
       })
   }
   
   // catch
   Promise.prototype.catch = function (onRejected) {
       return this.then(undefined, onRejected);
   }

   // resolve
   Promise.resolve = function (value) {
       // 根据value判断具体返回啥
       return new Promise((resolve, reject) => {
           if (value instanceof Promise) {
               value.then(resolve, reject);
           }else{//不是promise
               resolve(value);
           }
       })
   }

   // reject
   Promise.reject = function (reason) {
       // 直接返回一个失败的promise
       return new Promise((resolve, reject) => {
           reject(reason);
       })
       
   }

   // all
   Promise.all = function (promises) {
       const values = new Array(promises.length);
       let count = 0;

       return new Promise ((resolve, reject) => {
           promises.forEach((p, index) => {
               Promise.resolve(p).then(
                   value => {
                       count ++;
                       values[index] = value;
                       if (count == promises.length) {
                           resolve(values);
                       }
                   },
                   reason => {
                       reject(reason);
                   }
               )
           })
       })
   }
   
   // race
   Promise.race = function (promises) {
       return new Promise((resolve, reject) => {
           promises.forEach((p, index) => {
               Promise.resolve(p).then(
                   value => {
                       resolve(value);
                   },
                   reason => {
                       reject(reason);
                   }
               )
           })
       }) 
   }

   Promise.resolveDelay = function (value, time) {
       
       return new Promise((resolve, reject) => {
           setTimeout(() => {
               if (value instanceof Promise) {
                   value.then(resolve, reject);
               }else{//不是promise
                   resolve(value);
               }
           }, time)
       })
   }

   Promise.rejectDelay = function (reason, time) {
       return new Promise((resolve, reject) => {
           setTimeout(() => {
           reject(reason);
           }, time)
       })
   }

   window.Promise = Promise;//向外暴露promise
})(window)

// 自定义Promise函数模块:IIFE
(function (window) {
    // 常量一般用全大写来命名
    const PENDING = 'pending';
    const RESOLVED = 'resolved';
    const REJECTED = 'rejected';      
    // excutor同步执行
    class Promise {
        constructor(excutor) {
            const self = this;
            this.status = PENDING;
            this.data = undefined;
            this.callbacks = [];
    
            function resolve(value) {
                if (self.status !== PENDING) {
                    return ;
                }
                self.status = RESOLVED;//修改状态
                self.data = value;//保存value
    
                // 如果有待执行的callback函数,立即异步执行回调
                if (self.callbacks.length > 0) {
                    setTimeout(() => {//放入队列
                        self.callbacks.forEach(calobj => {
                            calobj.onResolved(value);
                        });
                    }, 0)
                }
            }
            function reject(reason) {
                if (self.status !== PENDING) {
                    return ;
                }
                self.status = REJECTED;//修改状态
                self.data = reason;//保存value
    
                // 如果有待执行的callback函数,立即异步执行回调
                if (self.callbacks.length > 0) {
                    setTimeout(() => {
                        self.callbacks.forEach(calobj => {
                            calobj.onRejected(reason);
                        });
                    }, 0)
                }
            }
    
            try{
                excutor(resolve, reject);
            }catch(error){
                reject(error);
            }
        }
            // then
        then (onResolved, onRejected) {
            onResolved = typeof onResolved === 'function' ? onResolved : value => value;
            onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw reason}//用于判断是否是异常传递
            
            const self = this;

            return new Promise((resolve, reject) => {

                function handle(callback) {
                    // 三种情况,1. 抛出异常2. 返回非promise3. 返回promise
                    try {
                        const result = callback(self.data);

                        if (result instanceof Promise) {
                        //  result.then(
                        //      value => resolve(value), 
                        //      reason => reject(reason)
                        //  )
                        result.then(resolve, reject);
                        }else{
                        resolve(result);
                        }
                        } catch (error) {
                            reject(error);
                        }
                }
                if (self.status === PENDING) {
                    self.callbacks.push(
                        {onResolved(value) {
                            handle(onResolved);
                        },
                        onRejected(reason) {
                            handle(onRejected);
                        }}
                    )
                }else if (self.status === RESOLVED) {
                    setTimeout(() => {
                        handle(onResolved);
                    }, 0)
                }else{
                    setTimeout(() => {
                        handle(onRejected);
                    }, 0)
                }
            })
        }
        
        // catch
        catch (onRejected) {
            return this.then(undefined, onRejected);
        }

        // resolve
        static resolve (value) {
            // 根据value判断具体返回啥
            return new Promise((resolve, reject) => {
                if (value instanceof Promise) {
                    value.then(resolve, reject);
                }else{//不是promise
                    resolve(value);
                }
            })
        }

        // reject
        static reject (reason) {
            // 直接返回一个失败的promise
            return new Promise((resolve, reject) => {
                reject(reason);
            })
            
        }

        // all
        static all (promises) {
            const values = new Array(promises.length);
            let count = 0;

            return new Promise ((resolve, reject) => {
                promises.forEach((p, index) => {
                    Promise.resolve(p).then(
                        value => {
                            count ++;
                            values[index] = value;
                            if (count == promises.length) {
                                resolve(values);
                            }
                        },
                        reason => {
                            reject(reason);
                        }
                    )
                })
            })
        }
        
        // race
        static race (promises) {
            return new Promise((resolve, reject) => {
                promises.forEach((p, index) => {
                    Promise.resolve(p).then(
                        value => {
                            resolve(value);
                        },
                        reason => {
                            reject(reason);
                        }
                    )
                })
            }) 
        }

        static resolveDelay (value, time) {
            
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    if (value instanceof Promise) {
                        value.then(resolve, reject);
                    }else{//不是promise
                        resolve(value);
                    }
                }, time)
            })
        }

        static rejectDelay (reason, time) {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                reject(reason);
                }, time)
            })
        }
    }
    
    


    window.Promise = Promise;//向外暴露promise
})(window)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值