乐趣区

关于es6:手动实现promise源码

promise 是异步解决方案,解决回调天堂问题。promise 从语法上来说是一个构造函数。从性能来说封装异步操作,并且能够获取其操作后果。

1. 根本用法

    const p =new Promise((resolve,reject)=>{setTimeout(()=>{
            // 异步操作
            resolve(value)
        },100)

    })

构造函数 Promise 的参数为一个执行器函数,执行器函数的参数为 resolve 与 reject 别离代表:第一个回调函数是 Promise 对象的状态变为 resolved 时调用,第二个回调函数是 Promise 对象的状态变为 rejected 时调用
2.Promise 构造函数的实现

Promise 对象外部含有三种状态,初始值 pending 已胜利 resolved 已失败 rejected
外部的状态在执行过程中,状态只能扭转一次并且不可逆。

初始化 初始时候将 status 的状态为 pending callbacks 用来保留胜利的与失败的回调函数

        self.status =PENDING
        self.data =undefined
        self.callbacks =[] // 每个元素构造 {onResolved(){}  onRejected(){}}
    function Promise(excutor){
        const self =this
        self.status =PENDING
        self.data =undefined
        self.callbacks =[] // 每个元素构造 {onResolved(){}  onRejected(){}}
        function resolve(value){
            // resolve 函数的作用将 promise 状态变为 resolved
            if(self.status!==PENDING){
                // 如果不是 pending 状态间接返回
                return
            }
            self.status =RESOLVED
            self.data = value
            if(self.callbacks.length>0){setTimeout(() => {
                    self.callbacks.forEach(callbacksObj => {callbacksObj.onResolved(value)
                        
                    });  
                },0);
    
            }
        }
        function reject(reason){if(self.status!==PENDING){return}
            self.status =REJECTED
            self.data = reason
            if(self.callbacks.length>0){setTimeout(() => {
                   // 遍历回调队列
                    self.callbacks.forEach(callbacksObj => {callbacksObj.onRejected(reason)
                        
                    });  
                });
    
            }

        }
       // 立刻同步执行 ex
       try{excutor(resolve,reject)

       }catch(err){reject(err)
       }       
    }

3.promise 实例的 then 办法

then 办法的第一个参数是 resolved 状态的回调函数,第二个参数是 rejected 状态的回调函数,它们都是可选的。并且返回也是一个 Promise 对象有三种状况 
  • 如果回调函数返回是 promise return 的 promise 的后果就是这个 promise 的后果
  • 如果回调函数返回不是 promise return 的 promise 就会胜利 value 就是返回值
  • 如果抛出异样 return 的 promise 就会失败 resaon 就是 error
    Promise.prototype.then=function(onResolved,onRejected){
        const self =this
        onResolved = typeof onResolved === 'function' ? onResolved :value =>value
        onRejected = typeof onRejected === 'function' ? onRejected :reason =>{throw reason}
        // 返回一个新的 promise 对象 
        return new Promise((resolve,reject)=>{
        // 调用指定的回调函数解决、依据执行后果 扭转 return 的 promise 状态
        function handle(callback){
            try{const result =callback(self.data)
                if(result instanceof Promise){
                    // 如果回调函数返回是 promise return 的 promise 的后果就是这个 promise 的后果
                    result.then(value =>{resolve(value)

                    },reason =>{reject(reason)

                    })
                    // result.then(resolve,reject)

                }else{
                    // 如果回调函数返回不是 promise return 的 promise 就会胜利 value 就是返回值
                    resolve(result)
                }
            }catch(error){
             // 如果抛出异样 return 的 promise 就会失败 resaon 就是 error
                reject(error)

            } 
        }
            if(self.status === PENDING){
                self.callbacks.push({onResolved(){handle(onResolved)
                    },
                    onRejected(){handle(onRejected) 
                    }
                })
    
            }else if(self.status === RESOLVED){setTimeout(()=>{handle(onResolved)
                })
    
            }else{setTimeout(()=>{handle(onRejected)
                })
            }
        })
         
    }

4.Promise 对象的 catch 办法

 作用来捕捉产生谬误的回调办法 
    Promise.prototype.catch=function(onRejected){return this.then(undefined,onRejected)  
    }

5 Promise 的 resolve 办法

 作用是将对象变为 Promise 对象。如果 resolve 办法参数是非 Promise 对象间接将 value 传递上来,如果是 Promise 对象 value 的后果将作为 Promise 的后果
    Promise.resolve = function(value){return new Promise((resolve,reject)=>{
            //value 是 promise
            if(value instanceof Promise){
                // 应用 value 的后果作为 promise 的后果
                value.then(resolve,reject)
            }else{
                  //value 不是 promise
                  resolve(value)
            }
        })
    }

6.Promise 的 reject 办法

 作用返回一个 rejected 的 Promise 对象
    Promise.reject = function(reason){return new Promise((resolve,reject)=>{reject(reason)
        })
    }

7.Promise 的 all 办法

  作用:执行多个 Promise 并返回新的 Promise 实例
  all 办法接管一个数组参数:
  • 如果 Promise 对象全副胜利,将返回一个数组保留每个胜利的 Promise 的返回值。
  • 如果有一个 Promise 对象失败 新的 Promise 将变为失败 返回值为执行失败的 Promise 的返回值
    Promise.all = function(promises){
        // 用来保留所有胜利 value 的数组
        const values =new Array(promises.length)
        // 用来保留胜利 promise 的数量
        let count = 0 
        return new Promise((resolve,reject)=>{
            // 获取每个 promise 的后果
            promises.forEach((p,index)=>{Promise.resolve(p).then(value=>{
                    count++
                    values[index] = value // 保留胜利的值
                    // 如果全副胜利了,将 return 的 promise 变为胜利

                    if(count === promises.length){resolve(values)
                    }
                },reason =>{reject(reason)
                })

            })
        })

    }

8.Promise 的 race 办法

 作用:返回一个新的 Promise 对象,最先执行实现 Promise 的返回值作为新的 Promise 对象的后果
    Promise.race = function(promises){return new Promise((resolve,reject)=>{
            // 获取每个 promise 的后果
            promises.forEach((p)=>{Promise.resolve(p).then(value=>{resolve(value)
                },reason =>{reject(reason)
                })
            })
        })
    }
退出移动版