关于javascript:特皮团队一年菜鸟实现Promise所有方法

从零手写Promise完整版

  • 随着前端技术的一直倒退,用户对界面的要求也在一直进步,当初的前端不再是之前的html+css, 而是html+css+js,然而想学好js首先要晓得js的外围在于异步,说到异步大部分人第一工夫会想到Promise
  • 那么接下来咱们就来学习一下Promise是如何实现的吧。
  • 首先咱们回顾一下Promise的根本应用
const p = new Promise((resolve,reject)=>{
    resolve('返回胜利的值')
    reject('返回失败的值')
})

p.then(value=>{
    console.log(value) // 返回胜利的值
})
  1. new Promise构造函数内的回调数是同步执行的
  2. then的回调函数,是异步执行的
  3. 调用resolve/reject后,状态已定,状态不能再扭转
  4. .then每次返回的都是新的Promise
  5. Promise能够嵌套

接着咱们从零开始来实现一下Promise

  • 先来实现明确一下根本的构造
(function(window){
    // 定义MyPromise构造函数
    function MyPromise(executor){

        function resolve(value){

        }
        function reject(reason){

        }
        executor(resolve,reject)
    }
    // MyPromise原型链上存在then办法
    MyPromise.prototype.then = function(onResolved,onRejected){

    }
    //MyPromise原型链上存在catch办法
    MyPromise.prototype.catch = function(onRejected){

    }

    //MyPromise实例对象上存在resolve办法
    MyPromise.resolve = function(value){

    }

    //MyPromise实例对象上存在reject办法
    MyPromise.reject = function(reason){

    }

    //MyPromise实例对象上存在all办法
    MyPromise.all = function(promises){

    }

    //MyPromise实例对象上存在race办法
    MyPromise.race = function(promises){
        
    }

    window.MyPromise = MyPromise;
})(window)
  • 明确来了根本的构造后,接下里咱们来看看MyPromise构造函数内须要做什么
  • 1.定义Promise的初始状态、初始值、寄存待执行异步函数的数组
(function(window){
    const PENDDING = 'pendding';
    const FULFILLED = 'fulfilled';
    const REJECTED = 'rejected';
    function MyPromise(executor){
        const self = this;
        self.status = PENDDING; //初始状态
        self.data = undefined; // 初始值
        self.callbacks = []; // 待执行异步回调函数的数组
    
        function resolve(value){
        }
        function reject(reason){
        }
        executor(resolve,reject)
    }
    window.MyPromise = MyPromise;
})(window)
    1. 依据Promise状态的不同,进行修,赋值,以及立刻执行异步回调
(function (window) {
    const PENDDING = 'pendding';
    const FULFILLED = 'fulfilled';
    const REJECTED = 'rejected';
    // 定义MyPromise
    function MyPromise(executor) {
        const self = this;
        self.status = PENDDING;
        self.data = undefined;
        self.callbacks = [];

        function resolve(value) {
            self.status = FULFILLED;
            self.data = value;
            // 立刻执行异步回调函数
            setTimeout(() => {
                self.callbacks.forEach(callbacksObj => {
                    callbacksObj.onResolved(value);
                })
            })
        }

        function reject(reason) {
            self.status = REJECTED;
            self.data = reason;
            setTimeout(() => {
                self.callbacks.forEach(callbacksObj => {
                    callbacksObj.onRejected(reason);
                })
            })
        }
        executor(resolve, reject)
    }
    window.MyPromise = MyPromise;
    1. 别忘了Promise 的状态一旦扭转就不能再批改了,所以在resolve/reject函数内须要加一个判断
(function (window) {
    const PENDDING = 'pendding';
    const FULFILLED = 'fulfilled';
    const REJECTED = 'rejected';
    // 定义MyPromise
    function MyPromise(executor) {
        const self = this;
        self.status = PENDDING;
        self.data = undefined;
        self.callbacks = [];

        function resolve(value) {
            if (self.status !== PENDDING) return;
            self.status = FULFILLED;
            self.data = value;
            // 立刻执行异步回调函数
            setTimeout(() => {
                self.callbacks.forEach(callbacksObj => {
                    callbacksObj.onResolved(value);
                })
            })
        }

        function reject(reason) {
            if (self.status !== PENDDING) return;
            self.status = REJECTED;
            self.data = reason;
            setTimeout(() => {
                self.callbacks.forEach(callbacksObj => {
                    callbacksObj.onRejected(reason);
                })
            })
        }
        executor(resolve, reject)
    }
    window.MyPromise = MyPromise;
    1. Promise原型链上的then办法,能够接管两个参数(且是回调函数),胜利/失败,并且每次返回的都是一个新的Promise
// MyPromise原型链上存在then办法
MyPromise.prototype.then = function (onResolved, onRejected) {
    const self = this;
    return new MyPromise((resolve, reject) => { // 每次都返回一个新的Promise对象
        // 首先判断以后状态
        if (self.status === FULFILLED) {
            /* 
                1、返回的Promise的后果是由onResolved/onrejected决定的
                2、返回的是Promise对象 (依据执后果决定Promise的返回后果)
                3、返回的不是Promise对象 (该值就是Promise的返回后果)
                4、抛出异样 异样的值为返回的后果
            */
            setTimeout(() => {
                try {
                    const result = onResolved(self.data);
                    if (reject instanceof MyPromise) {
                        result.then(value => {
                            resolve(value);
                        }, reason => {
                            reject(reason);
                        })
                    } else {
                        resolve(result);
                    }
    
                } catch (error) {
                    reject(error);
                }
            });
    
        } else if (self.status === REJECTED) {
            setTimeout(() => {
                try {
                    const result = onRejected(self.data);
                    if (reject instanceof MyPromise) {
                        result.then(value => {
                            resolve(value);
                        }, reason => {
                            reject(reason);
                        })
                    } else {
                        resolve(result);
                    }
    
                } catch (error) {
                    reject(error);
                }
            });
    
        } else if (self.status === PENDDING) {
            self.callbacks.push({
                onResolved() {
                    try {
                        const result = onResolved(self.data);
                        if (reject instanceof MyPromise) {
                            result.then(value => {
                                resolve(value);
                            }, reason => {
                                reject(reason);
                            })
                        } else {
                            resolve(result);
                        }
    
                    } catch (error) {
                        reject(error);
                    }
                },
                onRejected() {
                    try {
                        const result = onRejected(self.data);
                        if (reject instanceof MyPromise) {
                            result.then(value => {
                                resolve(value);
                            }, reason => {
                                reject(reason);
                            })
                        } else {
                            resolve(result);
                        }
    
                    } catch (error) {
                        reject(error);
                    }
                }
            })
        }
    })
}
  • 好的停一下,一步一步解说
    1. .then每次都返回一个新的Promise,所以在.then办法里是

> return new MyPromise((resolve,reject)){}

    1. 每一种状态都存在返回值,并且都能是一下三种状况
    2. 返回的是Promise对象
    3. 返回的不是Promise对象
    4. 抛出异样
    1. FULFILLED/REJECTED两种状态须要立刻执行异步函数
    1. PENDDING为什么没有立刻执行异步函数,因为当状态为PENDDING时就执行then,会先往待执行回调函数的数组(callbacks)内寄存这个回调,紧接着在回到Promise的执行其中执行resolve/reject,而下面也写过了,执行resolve/reject会去待执行回调函数的数组内遍历并赋值。

  • 好的持续,并且对下面反复的优化一下。
// MyPromise原型链上存在then办法
    MyPromise.prototype.then = function (onResolved, onRejected) {
        const self = this;
        return new MyPromise((resolve, reject) => { // 每次都返回一个新的Promise对象
            function handle(callback) {
                /* 
                    1、返回的Promise的后果是由onResolved/onrejected决定的
                    2、返回的是Promise对象 (依据执后果决定Promise的返回后果)
                    3、返回的不是Promise对象 (该值就是Promise的返回后果)
                    4、抛出异样 异样的值为返回的后果
                */
                try {
                    const result = callback(self.data);
                    if (reject instanceof MyPromise) {
                        result.then(value => {
                            resolve(value);
                        }, reason => {
                            reject(reason);
                        })
                    } else {
                        resolve(result);
                    }

                } catch (error) {
                    reject(error);
                }
            }
            // 首先判断以后状态
            if (self.status === FULFILLED) {
                setTimeout(() => {
                    thandle(onResolved)
                });

            } else if (self.status === REJECTED) {
                setTimeout(() => {
                    thandle(onRejected)
                });

            } else if (self.status === PENDDING) {
                self.callbacks.push({
                    onResolved() {
                        handle(onResolved)
                    },
                    onRejected() {
                        handle(onRejected)
                    }
                })
            }
        })
    }
    1. 避免不穿胜利或者失败的回调函数,给胜利和失败都给一个默认回调函数
MyPromise.prototype.then = function (onResolved, onRejected) {
        const self = this;
        // 定义默认回调
        onResolved = typeof onResolved === "function" ? onResolved : value => value;
        onRejected = typeof onRejected === "function" ? onRejected : reason => {throw reason};
        return new MyPromise((resolve, reject) => { // 每次都返回一个新的Promise对象
            function handle(callback) {
                /* 
                    1、返回的Promise的后果是由onResolved/onrejected决定的
                    2、返回的是Promise对象 (依据执后果决定Promise的返回后果)
                    3、返回的不是Promise对象 (该值就是Promise的返回后果)
                    4、抛出异样 异样的值为返回的后果
                */
                try {
                    const result = callback(self.data);
                    if (reject instanceof MyPromise) {
                        result.then(value => {
                            resolve(value);
                        }, reason => {
                            reject(reason);
                        })
                    } else {
                        resolve(result);
                    }

                } catch (error) {
                    reject(error);
                }
            }
            // 首先判断以后状态
            if (self.status === FULFILLED) {
                setTimeout(() => {
                    thandle(onResolved)
                });

            } else if (self.status === REJECTED) {
                setTimeout(() => {
                    thandle(onRejected)
                });

            } else if (self.status === PENDDING) {
                self.callbacks.push({
                    onResolved() {
                        handle(onResolved)
                    },
                    onRejected() {
                        handle(onRejected)
                    }
                })
            }
        })
    }
    1. 接着咱们看看catch,其实就是

Promise.prototype.then(undefined,rejected)

  • 或者

Promise.prototype.then(null,rejected)

//MyPromise原型链上存在catch办法
  MyPromise.prototype.catch = function (onRejected) {
    return this.then(null, onRejected);
  }
  • 7、接下来实现一下 Promise.resolve/Promise.reject
/MyPromise实例对象上存在resolve办法
MyPromise.resolve = function (value) {
    if (value instanceof MyPromise) return value;
    return new MyPromise(resolve => resolve(value))             // 返回一个resolved状态的Promise对象
}

//MyPromise实例对象上存在reject办法
MyPromise.reject = function (reason) {
    return new MyPromise((resolve,reject) => reject(reason));  // 返回一个reject状态Promise对象
}
    1. 接下来实现一下Promise.all/Promise.race
//MyPromise实例对象上存在all办法
MyPromise.all = function (promises) {
    let promisesCount = 0
    let values = new Array(promises.length);
    return new MyPromise((resolve,reject)=>{
        promises.forEach((promise,index)=>{
            promise.then(value => {
                promisesCount++;
                values[index] = value;
                if (promisesCount === promises.length){
                    resolve(values);
                }
            },reason => {
                reject(reason);
            })
        })
    })

}
  • 好的,咱们来看看Promise.all实现的思路

      1. Promise.all 传入的是一个数组
      1. Promise.all返回的是一个数组
      1. Promise.all传入的数组中,每个Promise对象必须都正确能力返回正确的后果数组
      1. Promise.all传入的数组中任意一个对象返回错的后果,都会返回谬误的后果
  • 好的,其实咱们还少一个步骤就是Promise.all传入的数组的参数能够不是Promise的实例, 所以数组参数如果不是Promise实例,先调用Promise.resolve
//MyPromise实例对象上存在all办法
MyPromise.all = function (promises) {
    let promisesCount = 0
    let values = new Array(promises.length);
    return new MyPromise((resolve, reject) => {
      promises.forEach((promise, index) => {
        MyPromise.resolve(promise).then(value => {
          promisesCount++;
          values[index] = value;
          if (promisesCount === promises.length) {
            resolve(values);
          }
        }, reason => {
          reject(reason);
        })
      })
    })
}
  • Promise.race实现
//MyPromise实例对象上存在race办法
  MyPromise.race = function (promises) {
    return new MyPromise((resolve, reject) => {
      promises.forEach(promise => {
        MyPromise.resolve(promise).then(value => {
          resolve(value);
        }, reason => {
          reject(reason)
        })
      })
    })
  }
    • 好的,解释一下,

        1. Promise.race传入的也是一个数组
        1. 传入的Promise执行内容雷同的状况下,Promise.race返回的后果为数组中的第一个值
        1. 若传入的Promise执行内容不统一,有先后辨别,则后果为执行的最快的一个
    • 至此从零手写一个Promise实现了,其中包含

    Promise.prototype.then

    Promise.prototype.catch

    Promise.resolve

    Promise.reject

    Promise.all

    Promise.race

    
    (function (window) {
    
      const PENDDING = 'pendding';
      const FULFILLED = 'fulfilled';
      const REJECTED = 'rejected';
      // 定义MyPromise
      function MyPromise(executor) {
        const self = this;
        self.status = PENDDING;
        self.data = undefined;
        self.callbacks = [];
    
        function resolve(value) {
          if (self.status !== PENDDING) return;
          self.status = FULFILLED;
          self.data = value;
          // 立刻执行异步回调函数
          setTimeout(() => {
            self.callbacks.forEach(callbacksObj => {
              callbacksObj.onResolved(value);
            })
          })
        }
    
        function reject(reason) {
          if (self.status !== PENDDING) return;
          self.status = REJECTED;
          self.data = reason;
          setTimeout(() => {
            self.callbacks.forEach(callbacksObj => {
              callbacksObj.onRejected(reason);
            })
          })
        }
        try{
          executor(resolve, reject)
        }catch(error){
          reject(error)
        }
        
      }
      // MyPromise原型链上存在then办法
      MyPromise.prototype.then = function (onResolved, onRejected) {
        const self = this;
        // 定义默认回调
        onResolved = typeof onResolved === "function" ? onResolved : value => value;
        onRejected = typeof onRejected === "function" ? onRejected : reason => {
          throw reason
        };
        return new MyPromise((resolve, reject) => { // 每次都返回一个新的Promise对象
          function handle(callback) {
            /* 
                1、返回的Promise的后果是由onResolved/onrejected决定的
                2、返回的是Promise对象 (依据执后果决定Promise的返回后果)
                3、返回的不是Promise对象 (该值就是Promise的返回后果)
                4、抛出异样 异样的值为返回的后果
            */
            try {
              const result = callback(self.data);
              if (reject instanceof MyPromise) {
                result.then(value => {
                  resolve(value);
                }, reason => {
                  reject(reason);
                })
              } else {
                resolve(result);
              }
    
            } catch (error) {
              reject(error);
            }
          }
          // 首先判断以后状态
          if (self.status === FULFILLED) {
            setTimeout(() => {
              handle(onResolved)
            });
    
          } else if (self.status === REJECTED) {
            setTimeout(() => {
              handle(onRejected)
            });
    
          } else if (self.status === PENDDING) {
            self.callbacks.push({
              onResolved() {
                handle(onResolved)
              },
              onRejected() {
                handle(onRejected)
              }
            })
          }
        })
      }
      //MyPromise原型链上存在catch办法
      MyPromise.prototype.catch = function (onRejected) {
        return this.then(null, onRejected);
      }
    
      //MyPromise实例对象上存在resolve办法
      MyPromise.resolve = function (value) {
        if (value instanceof MyPromise) return value;
        return new MyPromise(resolve => resolve(value)) // 返回一个resolved状态的Promise对象
      }
    
      //MyPromise实例对象上存在reject办法
      MyPromise.reject = function (reason) {
        return new MyPromise((resolve, reject) => reject(reason)); // 返回一个reject状态Promise对象
      }
    
      //MyPromise实例对象上存在all办法
      MyPromise.all = function (promises) {
        let promisesCount = 0
        let values = new Array(promises.length);
        return new MyPromise((resolve, reject) => {
          promises.forEach((promise, index) => {
            MyPromise.resolve(promise).then(value => {
              promisesCount++;
              values[index] = value;
              if (promisesCount === promises.length) {
                resolve(values);
              }
            }, reason => {
              reject(reason);
            })
          })
        })
      }
    
      //MyPromise实例对象上存在race办法
      MyPromise.race = function (promises) {
        return new MyPromise((resolve, reject) => {
          promises.forEach(promise => {
            MyPromise.resolve(promise).then(value => {
              resolve(value);
            }, reason => {
              reject(reason)
            })
          })
        })
      }
    
      window.MyPromise = MyPromise;
    })(window)
    • 最初咱们用类(class)的形式实现一下
    (function (window) {
        const PENDDING = 'pendding';
        const FULFILLED = 'fulfilled';
        const REJECTED = 'rejected';
        // 定义MyPromise
        class MyPromise {
            constructor(executor) {
                const self = this;
                self.status = PENDDING;
                self.data = undefined;
                self.callbacks = [];
    
                function resolve(value) {
                    if (self.status !== PENDDING) return;
                    self.status = FULFILLED;
                    self.data = value;
                    // 立刻执行异步回调函数
                    setTimeout(() => {
                        self.callbacks.forEach(callbacksObj => {
                            callbacksObj.onResolved(value);
                        })
                    })
                }
    
                function reject(reason) {
                    if (self.status !== PENDDING) return;
                    self.status = REJECTED;
                    self.data = reason;
                    setTimeout(() => {
                        self.callbacks.forEach(callbacksObj => {
                            callbacksObj.onRejected(reason);
                        })
                    })
                }
                executor(resolve, reject)
            }
            // MyPromise原型链上存在then办法
            then(onResolved, onRejected) {
                const self = this;
                // 定义默认回调
                onResolved = typeof onResolved === "function" ? onResolved : value => value;
                onRejected = typeof onRejected === "function" ? onRejected : reason => {
                    throw reason
                };
                return new MyPromise((resolve, reject) => { // 每次都返回一个新的Promise对象
                    function handle(callback) {
                        /* 
                            1、返回的Promise的后果是由onResolved/onrejected决定的
                            2、返回的是Promise对象 (依据执后果决定Promise的返回后果)
                            3、返回的不是Promise对象 (该值就是Promise的返回后果)
                            4、抛出异样 异样的值为返回的后果
                        */
                        try {
                            const result = callback(self.data);
                            if (reject instanceof MyPromise) {
                                result.then(value => {
                                    resolve(value);
                                }, reason => {
                                    reject(reason);
                                })
                            } else {
                                resolve(result);
                            }
    
                        } catch (error) {
                            reject(error);
                        }
                    }
                    // 首先判断以后状态
                    if (self.status === FULFILLED) {
                        setTimeout(() => {
                            handle(onResolved)
                        });
    
                    } else if (self.status === REJECTED) {
                        setTimeout(() => {
                            handle(onRejected)
                        });
    
                    } else if (self.status === PENDDING) {
                        self.callbacks.push({
                            onResolved() {
                                handle(onResolved)
                            },
                            onRejected() {
                                handle(onRejected)
                            }
                        })
                    }
                })
            }
            //MyPromise原型链上存在catch办法
            catch (onRejected) {
                return this.then(null, onRejected);
            }
            //MyPromise实例对象上存在resolve办法
            static resolve(value) {
                if (value instanceof MyPromise) return value;
                return new MyPromise(resolve => resolve(value)) // 返回一个resolved状态的Promise对象
            }
            //MyPromise实例对象上存在reject办法
            static reject(reason) {
                return new MyPromise((resolve, reject) => reject(reason)); // 返回一个reject状态Promise对象
            }
            //MyPromise实例对象上存在all办法
            static all(promises) {
                let promisesCount = 0
                let values = new Array(promises.length);
                return new MyPromise((resolve, reject) => {
                    promises.forEach((promise, index) => {
                        MyPromise.resolve(promise).then(value => {
                            promisesCount++;
                            values[index] = value;
                            if (promisesCount === promises.length) {
                                resolve(values);
                            }
                        }, reason => {
                            reject(reason);
                        })
                    })
                })
            }
            //MyPromise实例对象上存在race办法
            static race(promises) {
                return new MyPromise((resolve, reject) => {
                    promises.forEach(promise => {
                        MyPromise.resolve(promise).then(value => {
                            resolve(value);
                        }, reason => {
                            reject(reason)
                        })
                    })
                })
            }
        }
        window.MyPromise = MyPromise;
    })(window)
    • 从零手写Promise说难也不难,然而还是花了不少工夫的,心愿可能帮忙到像我一样想学好js,想学好Promise的敌人,一起加油吧。

    最初

    • 如果你想退出特皮技术团队,有人领导你学习,晋升本人,能够公众号分割我
    • 感觉对你有帮忙,能够点个在看,转发一下,关注咱们公众号:【前端巅峰

    评论

    发表回复

    您的邮箱地址不会被公开。 必填项已用 * 标注

    这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理