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)

猜你喜欢

转载自blog.csdn.net/weixin_50948265/article/details/118992791