实现一个promise

promise对象的结构

promise对象中有状态PromiseState,值PromiseResult以及原型组成

Promise对象有三种状态,分别是pending、fulfilled和rejected 。其中,pending表示等待态,fulfilled表示执行态,rejected表示拒绝态。

var promise = new Promise((resolve,reject) => {})
console.log(promise);

img

简单搭建一个promise对象
        // 简单搭建promise
        function MyPromise(){
            //声明状态和值并赋值初始值
            this.PromiseState = 'pedding'
            this.promiseResult = null
        }

promise对象的参数

promise对象有一个函数作为参数,其中这个函数又有两个参数,分别为resolve、reject。两者都是函数。

给promise填充参数
        function MyPromise(fn){
            this.PromiseState = 'pedding'
            this.promiseResult = null
            function resolve(data){

            };
            function reject(data){

            };
            // 如果promise存在传入的函数,则执行
            if (fn) {
                fn(resolve, reject);
            }
        }
丰富resolve和reject

resolve参数是一个函数。这个函数接收一个参数,并返回一个新的Promise对象。当调用resolve函数时,它会将当前Promise对象的状态从pending变为fulfilled,并将传入的参数作为新Promise对象的值。如果传入的参数不是一个Promise对象,那么它会被立即执行,并作为新Promise对象的值。

reject参数也是一个函数。这个函数接收一个参数,并返回一个新的Promise对象。当调用reject函数时,它会将当前Promise对象的状态从pending变为rejected,并将传入的参数作为新Promise对象的值。如果传入的参数不是一个Promise对象,那么它会被立即执行,并作为新Promise对象的值。

        function MyPromise(fn){
            this.PromiseState = 'pedding'
            this.PromiseResult = null
            // MyPromise函数实例对象中的this
            const self = this
            function resolve(data){
                self.PromiseState = 'fulfilled'
                self.PromiseResult = data
            };
            function reject(data) {
                self.PromiseState = 'rejected'
                self.PromiseResult = data
            }
            if (fn) {
                fn(resolve, reject);
            }
        }

promise对象的特性

Promise中的对象状态只能转换一次。一旦Promise对象的状态被改变(从pending变为fulfilled或rejected),它就不能再改变状态了。如果尝试再次改变状态,将会抛出一个错误。

function MyPromise(fn){
      this.PromiseState = 'pedding'
      this.PromiseResult = null
      const self = this
      function resolve(data){        
        // 加上了状态的限制
          if (self.PromiseState !== 'pedding') return
          self.PromiseState = 'fulfilled'
          self.PromiseResult = data
      };
      function reject(data) {
          self.PromiseState = 'rejected'
          if (self.PromiseState !== 'pedding') return
          self.PromiseResult = data
      }
      if (fn) {
          fn(resolve, reject);
      }
  }

promise对象的原型方法

then方法

then方法接受两个回调函数作为参数,如果promise对象的状态为fulfilled时,执行第一个,状态为rejected时,执行第二个

    	// 定义对象原型上的then方法
        MyPromise.prototype.then = function (onResolved, onRejected) {
            // 调用回调函数
            if(this.promiseState === 'resolved') {
                onResolved(this.promiseResult)
            }
            if(this.promiseState === 'rejected') {
                onRejected(this.promiseResult)
            }
        }

then方法中还需要添加一个回调函数,判断当前的状态是否为pedding,如果为pedding,保存resolve中的未执行异步任务。

        //声明一个对象保存resolve中的未执行异步任务
        this.callback = {}
        MyPromise.prototype.then = function (onResolved, onRejected) {
            //PromiseState是否为pedding
            if (this.PromiseState === 'pedding') {
            //保存回调函数
                this.callback = {
                    onResolved: onResolved,
                    onRejected: onRejected
                }
            }
            if(this.PromiseState === 'resolved') {
                onResolved(this.PromiseResult)
            }
            if(this.PromiseState === 'rejected') {
                onRejected(this.PromiseResult)
            }
        }

存储了回调函数,则需要修改resolve和reject里面的回调函数执行逻辑

    function resolve(data) {
        if (self.PromiseState !== 'pedding') return
        self.PromiseState = 'resolved'
        self.PromiseResult = data

        //调用then
        if (self.callback.onResolved) {
            self.callback.onResolved(data)
        }
    }
    function reject(data) {
        if (self.PromiseState !== 'pedding') return
        self.PromiseState = 'rejected'
        self.PromiseResult = data

        //调用then
        if (self.callback.onRejected) {
            self.callback.onRejected(data)
        }
    }
catch方法

promise多个回调执行实现

promise.then方法会返回一个新的Promise 对象。这个新的 Promise 对象的状态和值取决于上一个 Promise 对象的状态和值。

修改回调函数调用逻辑,改为数组,存储多个回调函数

//存储多个未调用的回调函数
this.callback = []
//PromiseState是否为pedding
if (this.PromiseState === 'pedding') {
//保存回调函数
    this.callback.push({
        onResolved: onResolved,
        onRejected: onRejected
    })
}
// 回调函数执行逻辑修改
self.callbacks.forEach(item => {
    item.onResolved(data)
}) 
self.callbacks.forEach(item => {
    item.onRejected()
})
修改then方法
Promise.prototype.then = function (onResolved, onRejected) {
    return new Promise((resolve, rejecte) => {
        if (this.PromiseState === 'resolved') {
            try{
              let result = onResolved(this.promiseResult)
              //如果result是一个promise对象
              if(result instanceof Promise) {
                  result.then(value => {
                      resolve(value);
                  }, result=> {
                      reject(result)
                  })
              }else {
                  resolve(result)
              }
            }catch(error){
                reject(error)
            }
        }
      ...

then方法本质上是一个递归,一直会循环调用,直到返回值不是一个promise对象。

promise异步修改then方法的状态
if (this.PromiseState === 'pedding') {
    //保存回调函数
    this.callbacks.push({
        onResolved: function() {
            let result = onResolved(self.PromiseResult)
            if(result instanceof Promise) {
                result.then(value => {
                      resolve(value);
                  }, result=> {
                      reject(result)
                  })
            }else {
                resolve(result)
            }
        },

promise最终实现

        function MyPromise(fn){
            this.PromiseState = 'pedding'
            this.PromiseResult = null
            //存储多个未调用的回调函数
            this.callback = []
            const self = this
            function resolve(data) {
                if (self.PromiseState !== 'pedding') return
                self.PromiseState = 'resolved'
                self.PromiseResult = data
                if (self.callback.onResolved) {
                    // 回调函数执行逻辑修改
                    self.callbacks.forEach(item => {
                        item.onResolved(data)
                    }) 
                }
            }
            function reject(data) {
                if (self.PromiseState !== 'pedding') return
                    self.PromiseState = 'rejected'
                    self.PromiseResult = data
                if (self.callback.onRejected) {
                    self.callbacks.forEach(item => {
                        item.onRejected()
                    })
                }
            }
            
            try {
                fn(resolve, reject);
            } catch (error) {
                reject(error)
            }
        }
        // 定义对象原型上的then方法
        MyPromise.prototype.then = function (onResolved, onRejected) {
            const self = this
            if (this.PromiseState === 'pedding') {
            //保存回调函数
                this.callback.push({
                    onResolved: function() {
                        let result = onResolved(self.PromiseResult)
                        if(result instanceof Promise) {
                            result.then(value => {
                                resolve(value);
                            }, result=> {
                                reject(result)
                            })
                        }else {
                            resolve(result)
                        }
                    },
                    onRejected: function() {
                        let result = onRejected(self.PromiseResult)
                        if(result instanceof Promise) {
                            result.then(value => {
                                resolve(value);
                            }, result=> {
                                reject(result)
                            })
                        }else {
                            resolve(result)
                        }
                    }
                })
            }
            if(this.promiseState === 'resolved') {
                try{
                    let result = onResolved(this.PromiseResult)
                    if(result instanceof Promise) {
                        result.then(value => {
                            resolve(value);
                        }, result=> {
                            reject(result)
                        })
                    }else {
                        resolve(result)
                    }
                }catch(e) {
                    reject(e)
                }
            }
            if(this.promiseState === 'rejected') {
                try{
                    let result = onRejected(this.PromiseResult)
                    if(result instanceof Promise) {
                        result.then(value => {
                            resolve(value);
                        }, result=> {
                            reject(result)
                        })
                    }else {
                        resolve(result)
                    }
                }catch(e) {
                    reject(e)
                }
            }
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值