手写promise

42 阅读6分钟
 // 声明构造函数
        function Promise(executor) {
            //    添加属性
            this.PromiseState = 'pending';
            this.PromiseResult = null;

            //  定时一个数组来保存 当状态为pending回调函数  
            this.callbacks = []

            //  保存实例对象的this的值
            const self = this

            // resolve函数
            function resolve(data) {

                //  promise一旦修改了状态,就不能再修改了,判断状态
                if (self.PromiseState !== 'pending') return
                // 这里resolve是直接调用,this指向window所以,用保存的self
                // 1.修改对象成功状态
                self.PromiseState = 'fulfilled';
                // 2.设置对象结果
                self.PromiseResult = data
                // 这里改变了状态,pending=>fulfilled,把callbacks中回调函数遍历执行,
                // 但then方法是异步执行,所以要放在settimeOut里面
                setTimeout(() => {
                    self.callbacks.forEach(item => {
                        item.onResolved()
                        // 这里相当是  onResolved: function (){} 在执行
                    })
                })

            }
            // reject 函数
            function reject(data) {
                //  promise一旦修改了状态,就不能再修改了,判断状态
                if (self.PromiseState !== 'pending') return
                // 1.修改对象失败状态
                self.PromiseState = 'rejected';
                // 2.设置对象结果
                self.PromiseResult = data
                // 这里改变了状态,pending=>rejected,把callbacks中回调函数遍历执行
                // 但then方法是异步执行,所以要放在settimeOut里面
                setTimeout(() => {
                    self.callbacks.forEach(item => {
                        item.onRejected()
                        // 这里相当是  onRejected: function (){} 在执行
                    })
                })

            }

            // 同步调用( 执行器函数)
            try {
                executor(resolve, reject)
            } catch (error) {
                // 当代码出错误或抛出异常,用try ,catch捕获,此时把对象修改为失败的状态
                reject(error)
            }

        }

        //  声明then方法,返回的是一个promise对象
        Promise.prototype.then = function (onResolved, onRejected) {

            // 判断传过来的参数有没有
            if (typeof onRejected !== 'function') {
                onRejected = reason => { throw reason }
                // 这也是catch穿透原理,
            }
            if (typeof onResolved !== 'function') {
                onResolved = value => value

            }
            // 封装重复代码
            function callback(type) {
                try {
                    //    获取回调函数的结果,用result接收
                    let result = type(self.PromiseResult)
                    //  判断
                    if (result instanceof Promise) {
                        //  是promise对像, result状态决定then返回的promise状态
                        result.then(
                            v => {
                                resolve(v)
                            },
                            r => {
                                reject(r)
                            })

                    } else {
                        // 不是promise对象,设置状态为成功
                        resolve(result)
                    }
                } catch (error) {
                    reject(error)
                    // 当抛出错误,用trycatch捕获
                }
            }

            // 保存this
            const self = this
            return new Promise((resolve, reject) => {


                // 调用回调函数,promiseState状态改变,调相应的函数
                // 此时的this指向实例对象
                if (this.PromiseState === 'fulfilled') {
                   setTimeout(()=>{
                    callback(onResolved)
                   })
                }
                if (this.PromiseState === 'rejected') {
                    setTimeout(()=>{
                        callback(onRejected)
                    })
                }
                // 判断pending时( 当改变状态时使用了延时,异步的情况下,)
                // 只能把回调的函数存起来,等改变了状态再调用:onResolved或onRejected
                if (this.PromiseState === 'pending') {
                    // 把回调函数 放在callbacks数组中,(不管有几个回调函数,解决多次调用)
                    this.callbacks.push({
                        // 包装成一个函数,里面再执行回调函数,实际为了判断,决定返回的promise对象的状态
                        onResolved: function () {
                            callback(onResolved)
                        },
                        onRejected: function () {
                            callback(onRejected)
                        }
                    })
                }
            })
        }

        // 声明catch方法
        Promise.prototype.catch = function (onRejected) {
            // 直接调用then方法
            return this.then(undefined, onRejected)

        }


        // 添加resolve方法
        Promise.resolve = function (value) {
            //  返回一个promise对象
            return new Promise((resolve, reject) => {
                if (value instanceof Promise) {
                    // 返回的promise对象状态由传入的promise对象状态决定
                    value.then(
                        v => { resolve(v) },
                        r => { reject(r) }
                    )
                } else {
                    // 当value不是promise对象,设置为成功
                    resolve(value)
                }
            })
        }
        // 添加reject方法, 永远返回的是失败promise对象
        Promise.reject = function (reason) {
            return new Promise((resolve, reject) => {
                reject(reason)
            })
        }

        // 添加all方法 ,返回的是一个promise对象,状态由传入的3个promise对象决定,
        Promise.all = function (promises) {
            return new Promise((resolve, reject) => {
                // 声明变量count 来控制传入的3个promise状态情况
                let count = 0;
                // 声明数组来保存返回的结果
                let arr = []

                // 要知道3个promise的状态就要遍历
                for (let i = 0; i < promises.length; i++) {
                    promises[i].then(

                        v => {
                            // 当成功就count+1
                            count++;
                            // 并把值放在数组中
                            arr[i] = v
                            // 判断
                            if (count === promises.length) {
                                // 长度等于promise的个数,说明三个都是成功的,再改变返回的promise状态
                                resolve(arr)
                            }

                        },
                        r => {
                            // 如果是失败,就直接修改失败的状态返回
                            reject(v)
                        }
                    )
                }
            })
        }


        // 添加race的方法,谁先执行完成就先执行回调。
      // 添加race的方法,谁先执行完成就先执行回调。
        Promise.race = function (promises) {
            return new Promise((resolve, reject) => {
                // 遍历
                for (let i = 0; i < promises.length; i++) {
                    promises[i].then(
                        v => {
                            resolve(v)
                            //  走到then方法,说明已经改变了状态了,谁先调用,就会改变返回的promise对象状态
                        },
                        r => {
                            reject(r)
                        }
                    )
                }
            })
        }

class类封装




    
         class promise{
            // 构造函数
            constructor(executor){
                 //    添加属性
            this.PromiseState = 'pending';
            this.PromiseResult = null;

            //  定时一个数组来保存 当状态为pending回调函数  
            this.callbacks = []

            //  保存实例对象的this的值
            const self = this

            // resolve函数
            function resolve(data) {

                //  promise一旦修改了状态,就不能再修改了,判断状态
                if (self.PromiseState !== 'pending') return
                // 这里resolve是直接调用,this指向window所以,用保存的self
                // 1.修改对象成功状态
                self.PromiseState = 'fulfilled';
                // 2.设置对象结果
                self.PromiseResult = data
                // 这里改变了状态,pending=>fulfilled,把callbacks中回调函数遍历执行,
                // 但then方法是异步执行,所以要放在settimeOut里面
                setTimeout(() => {
                    self.callbacks.forEach(item => {
                        item.onResolved()
                        // 这里相当是  onResolved: function (){} 在执行
                    })
                })

            }
            // reject 函数
            function reject(data) {
                //  promise一旦修改了状态,就不能再修改了,判断状态
                if (self.PromiseState !== 'pending') return
                // 1.修改对象失败状态
                self.PromiseState = 'rejected';
                // 2.设置对象结果
                self.PromiseResult = data
                // 这里改变了状态,pending=>rejected,把callbacks中回调函数遍历执行
                // 但then方法是异步执行,所以要放在settimeOut里面
                setTimeout(() => {
                    self.callbacks.forEach(item => {
                        item.onRejected()
                        // 这里相当是  onRejected: function (){} 在执行
                    })
                })

            }

            // 同步调用( 执行器函数)
            try {
                executor(resolve, reject)
            } catch (error) {
                // 当代码出错误或抛出异常,用try ,catch捕获,此时把对象修改为失败的状态
                reject(error)
            }
            }
            // then方法
            then(onResolved,onRejected){
                  // 判断传过来的参数有没有
            if (typeof onRejected !== 'function') {
                onRejected = reason => { throw reason }
                // 这也是catch穿透原理,
            }
            if (typeof onResolved !== 'function') {
                onResolved = value => value

            }
            // 封装重复代码
            function callback(type) {
                try {
                    //    获取回调函数的结果,用result接收
                    let result = type(self.PromiseResult)
                    //  判断
                    if (result instanceof Promise) {
                        //  是promise对像, result状态决定then返回的promise状态
                        result.then(
                            v => {
                                resolve(v)
                            },
                            r => {
                                reject(r)
                            })

                    } else {
                        // 不是promise对象,设置状态为成功
                        resolve(result)
                    }
                } catch (error) {
                    reject(error)
                    // 当抛出错误,用trycatch捕获
                }
            }

            // 保存this
            const self = this
            return new Promise((resolve, reject) => {


                // 调用回调函数,promiseState状态改变,调相应的函数
                // 此时的this指向实例对象
                if (this.PromiseState === 'fulfilled') {
                   setTimeout(()=>{
                    callback(onResolved)
                   })
                }
                if (this.PromiseState === 'rejected') {
                    setTimeout(()=>{
                        callback(onRejected)
                    })
                }
                // 判断pending时( 当改变状态时使用了延时,异步的情况下,)
                // 只能把回调的函数存起来,等改变了状态再调用:onResolved或onRejected
                if (this.PromiseState === 'pending') {
                    // 把回调函数 放在callbacks数组中,(不管有几个回调函数,解决多次调用)
                    this.callbacks.push({
                        // 包装成一个函数,里面再执行回调函数,实际为了判断,决定返回的promise对象的状态
                        onResolved: function () {
                            callback(onResolved)
                        },
                        onRejected: function () {
                            callback(onRejected)
                        }
                    })
                }
            })
            }
            // catch方法
            catch(onRejected){
                 // 直接调用then方法
            return this.then(undefined, onRejected)
            }
      
            static resolve(value){
                 //  返回一个promise对象
            return new Promise((resolve, reject) => {
                if (value instanceof Promise) {
                    // 返回的promise对象状态由传入的promise对象状态决定
                    value.then(
                        v => { resolve(v) },
                        r => { reject(r) }
                    )
                } else {
                    // 当value不是promise对象,设置为成功
                    resolve(value)
                }
            })
            }
       
            static reject(reason){
                return new Promise((resolve, reject) => {
                reject(reason)
            })
            }
      
            static all(promises){
                return new Promise((resolve, reject) => {
                // 声明变量count 来控制传入的3个promise状态情况
                let count = 0;
                // 声明数组来保存返回的结果
                let arr = []

                // 要知道3个promise的状态就要遍历
                for (let i = 0; i < promises.length; i++) {
                    promises[i].then(

                        v => {
                            // 当成功就count+1
                            count++;
                            // 并把值放在数组中
                            arr[i] = v
                            // 判断
                            if (count === promises.length) {
                                // 长度等于promise的个数,说明三个都是成功的,再改变返回的promise状态
                                resolve(arr)
                            }

                        },
                        r => {
                            // 如果是失败,就直接修改失败的状态返回
                            reject(v)
                        }
                    )
                }
            })
            }
            
            static race(promises){
                return new Promise((resolve, reject) => {
                // 遍历
                for (let i = 0; i < promises.length; i++) {
                    promises[i].then(
                        v => {
                            resolve(v)
                            //  走到then方法,说明已经改变了状态了,谁先调用,就会改变返回的promise对象状态
                        },
                        r => {
                            reject(r)
                        }
                    )
                }
            })
            }
       
        }