Promise复习(手写promise)---根据尚硅谷promise课程复习

目录

1.整体结构

   1.1观察原生promise

  1.2实现步骤

2.Promise的resolve,reject

2.1设置初始值

2.2抛出异常及状态一旦修改就不能改变

3.then方法的执行回调

3.1执行回调实现步骤

4.then方法修改状态返回结果

4.1实现步骤(同步)

4.2实现步骤(异步)

4.3封装函数及then方法回调的异步执行

1.封装函数

2.then方法回调的异步执行

5.Promise构造函数以及then方法(总结)

6.promise的相关方法的实现


1.整体结构

   1.1观察原生promise

  1. promise内部传入了一个参数且该参数是一个函数,并且该函数接收2个函数类型的参数(resolve,reject) 
  2. 并且还可以在内部执行操作,执行resolve方法
  3. 还可以发现then方法属于promise的实例方法,所以应该在promise的原型对象(prototype)中有一个then方法,并且then方法接收2个函数类型的参数
        let p = new Promise((resolve, reject) => {
            resolve('OK');
        });
        p.then(
            value => {
                console.log(value);   //ok
            },
            reason => {
                console.log(reason);
            }
        )

  1.2实现步骤

  1. 在promise构造函数内部定义一个excutor执行器函数
  2. 立即执行excutor执行器函数-----传入2个参数  resolve, reject (在内部定义好)
  3.  在promise的原型对象(prototype)上添加then方法---传入2个参数  onResolved,onRejected       
/*
自定义promise模块: IIFE
*/
(function (window) {
    /*
    Promise构造函数
    excutor: 执行器函数(同步执行)---传入2个参数 resolve,reject
    */
    function Promise(excutor) {

        function resolve(params){

        }
        function reject(params){

        }

        //立即同步执行excutor
        excutor(resolve, reject)
    }

    /*
    Promise原型对象的then()
    */
    Promise.prototype.then = function (onResolved, onRejected) {

    }

    // 向外暴露Promise函数
    window.Promise = Promise
})(window)

2.Promise的resolve,reject

一个 Promise 必然处于以下几种状态之一:

  • 待定(pending):初始状态,既没有被兑现,也没有被拒绝。
  • 已兑现(fulfilled):意味着操作成功完成。
  • 已拒绝(rejected):意味着操作失败

resolev函数传入value参数,reject函数传入reason参数

注意:resolve函数与reject函数基本一致,先以resolve举例

1.调用resolve函数后,promise的状态会发生改变(变为resolved),并且它可以设置promise对象成功的结果

2.调用resolve函数

2.1设置初始值

  1. 设置resolve,reject函数的参数
  2. 定义三个常量状态 resolved(fulfilled) rejected pending
  3. 设置promise初始状态为pending
  4. 设置promise的结果值
    const PENDING = 'pending'
    const RESOLVED = 'resolved'
    const REJECTED = 'rejected'
    /*
    Promise构造函数
    excutor: 执行器函数(同步执行)---传入2个参数 resolve,reject
    */
    function Promise(excutor) {

        //将当前promise对象保存起来
        const self=this
        self.status = PENDING //给promise对象指定status属性,初始值为pending
        self.data = undefined  //给promise对象指定一个用于存储结果的数据的类型

        function resolve(value) {
            //1.修改对象的状态为resolved
            self.status = RESOLVED
            //2.保存value数据
            self.data=value

        }
        function reject(reason) {

        }

        //立即同步执行excutor
        excutor(resolve, reject)
    }

2.2抛出异常及状态一旦修改就不能改变

     let p = new Promise((resolve, reject) => {
            reject('ok')
            resolve('hhh')
        });
        console.log(p); //rejectde

根据上图原生的promise,和结果可以得出

  1. 当promise抛出异常后,也可以改变promise的状态值(rejected),而且抛出的error会作为promise的值
  2. promise的状态只能修改一次

        function resolve(value) {
            //如果当前状态不是pending, 直接结束
            if (self.status !== PENDING) {
                return
            }
            //1.修改对象的状态为resolved
            self.status = RESOLVED
            //2.保存value数据
            self.data = value

        }
        function reject(reason) {

        }

        //立即同步执行excutor
        try {
            excutor(resolve, reject)
        } catch (error) {
            reject(error)
        }

3.then方法的执行回调

then方法可以接受两个回调函数作为参数。

第一个回调函数是Promise对象的状态变为resolved时调用,并输出结果值

第二个回调函数是Promise对象的状态变为rejected时调用,并输出结果值

在回调函数调用的时候会分成2种情况

1.在promise执行的是同步任务情况下,这个回调执行应该在then方法中执行

2.在promise执行的是异步任务情况下,这个回调执行应该先保存起来,在异步任务的时候执行

  let p1 = new Promise((resolve, reject) => {
            //第一种同步情况
            resolve('同步')
  });


  let 2p = new Promise((resolve, reject) => {
            //第二种同步情况
          setTimeout(()=>{
                resolve('异步')
            })
  });

3.1执行回调实现步骤

  1. 同步情况下需要判断promise的状态为什么,然后调用向对应的回调函数
  2. 异步情况下状态为pending,需要先保存回调函数,并等到promise状态判定完后进行执行,所以promise需要设定一个保存回调函数的数组(需要考虑promise可以执行多个异步回调),并且在resolve,reject方法里使用回调函数
/*
自定义promise模块: IIFE
*/
(function (window) {
    const PENDING = 'pending'
    const RESOLVED = 'resolved'
    const REJECTED = 'rejected'
    /*
    Promise构造函数
    excutor: 执行器函数(同步执行)---传入2个参数 resolve,reject
    */
    function Promise(excutor) {

        //将当前promise对象保存起来
        const self = this
        self.status = PENDING //给promise对象指定status属性,初始值为pending
        self.data = undefined  //给promise对象指定一个用于存储结果的数据的类型
        self.callbacks = []   //每个数组元素的结构: { onResolved() {}, onRejected() {}}

        function resolve(value) {
            //如果当前状态不是pending, 直接结束
            if (self.status !== PENDING) {
                return
            }
            //1.修改对象的状态为resolved
            self.status = RESOLVED
            //2.保存value数据
            self.data = value
            //3.如果有待执行callback函数, 立即执行回调函数onResolved
                self.callbacks.forEach(callback => {
                    callback.onResolved(value)
                });

        }
        function reject(reason) {
            //如果当前状态不是pending, 直接结束
            if (self.status !== PENDING) {
                return
            }
            //1.修改对象的状态为rejected
            self.status = REJECTED
            //2.保存value数据
            self.data = reason
            //3.如果有待执行callback函数, 立即执行回调函数onRejected
                self.callbacks.forEach(callback => {
                    callback.onRejected(reason)
                });
        }

        //立即同步执行excutor
        try {
            excutor(resolve, reject)
        } catch (error) {
            reject(error)
        }

    }

    /*
    Promise原型对象的then()
    */
    Promise.prototype.then = function (onResolved, onRejected) {
        const self = this
        //根据状态调用回调函数
        if (self.status === RESOLVED) { //resolved
            onResolved(self.data)
        } else if (self.status === REJECTED) { //rejected
            onRejected(self.data)
        } else {  //pending
            self.callbacks.push({
                onRejected,
                onResolved
            })

        }
    }

4.then方法修改状态返回结果

let p = new Promise((resolve, reject) => {
            //第一种
            resolve('同步')
            // setTimeout(()=>{
            //     resolve('异步')
            // })
        }).then(
            value=>{
                console.log('onResolved1 '+value);
                return 2
            },reason=>{
                console.log(reason);
            }
        ).then(
            value=>{
                console.log('onResolved2 '+value);
            },reason=>{
                console.log(reason);
            }
        )

由上图原生的promise可知

then方法返回的是一个promise ,并且返回promise的结果由onResolved/onRejected执行结果决定

大致分为:

  1.   抛出异常, 返回promise的结果为失败, reason为异常
  2.   返回的是promise, 返回promise的结果就是这个结果
  3.   返回的不是promise, 返回promise为成功, value就是返回值

4.1实现步骤(同步)

1.then方法返回的是一个promise,需要return一个promise

2返回promise的结果由onResolved/onRejected执行结果

  if (self.status === RESOLVED) { //resolved
                //返回promise的结果由onResolved/onRejected执行结果决定
                // 1. 抛出异常, 返回promise的结果为失败, reason为异常
                // 2. 返回的是promise, 返回promise的结果就是这个结果
                // 3. 返回的不是promise, 返回promise为成功, value就是返回值
                try {
                    const result = onResolved(self.data)
                    if (result instanceof Promise) { //第二种情况,返回的是promise
                        result.then(
                            value => resolve(vlaue),
                            reason => reject(reason)
                        )
                    } else { //第三种情况,不是promise
                        resolve(result)
                    }
                } catch (error) {
                    reject(error)
                }
            } else if (self.status === REJECTED) { //rejected
                try {
                    const result = onRejected(self.data)
                    if (result instanceof Promise) { //第二种情况,返回的是promise
                        result.then(
                            value => resolve(vlaue),
                            reason => reject(reason)
                        )
                    } else { //第三种情况,不是promise
                        resolve(result)
                    }
                } catch (error) {
                    reject(error)
                }

4.2实现步骤(异步)

else {  //pending
                self.callbacks.push({
                    onResolved(value){
                        try {
                            const result = onResolved(self.data)
                            if (result instanceof Promise) { //第二种情况,返回的是promise
                                result.then(
                                    value => resolve(vlaue),
                                    reason => reject(reason)
                                )
                            } else { //第三种情况,不是promise
                                resolve(result)
                            }
                        } catch (error) {
                            reject(error)
                        }
                    },
                    onRejected(reason){
                        try {
                            const result = onRejected(self.data)
                            if (result instanceof Promise) { //第二种情况,返回的是promise
                                result.then(
                                    value => resolve(vlaue),
                                    reason => reject(reason)
                                )
                            } else { //第三种情况,不是promise
                                resolve(result)
                            }
                        } catch (error) {
                            reject(error)
                        }
                    }
                })

4.3封装函数及then方法回调的异步执行

1.封装函数

由同步和异步的修改状态返回结果来看,我们可以将他们封装成一个函数 handle

根据执行的结果改变return的promise的状态/数据 ,执行指定的回调函数

  /* 
            执行指定的回调函数
            根据执行的结果改变return的promise的状态/数据
            */
            function handle(callback) {
                //返回promise的结果由onResolved/onRejected执行结果决定
                // 1. 抛出异常, 返回promise的结果为失败, reason为异常
                // 2. 返回的是promise, 返回promise的结果就是这个结果
                // 3. 返回的不是promise, 返回promise为成功, value就是返回值
                try {
                    const result = callback(self.data)
                    if (result instanceof Promise) { //第二种情况,返回的是promise
                        result.then(
                            value => resolve(vlaue),
                            reason => reject(reason)
                        )
                    } else { //第三种情况,不是promise
                        resolve(result)
                    }
                } catch (error) {
                    reject(error)
                }
            }

2.then方法回调的异步执行

let p = new Promise((resolve, reject) => {
            // //第一种
            // reject('同步')
            setTimeout(()=>{
                resolve('异步')
                console.log('你好');
            })
        }).then(
            value=>{
                console.log('onResolved1 '+value);
                return 2
            },reason=>{
                console.log(reason);
                throw 2
            }
        ).then(
            value=>{
                console.log('onResolved2 '+value);
            },reason=>{
                console.log(reason);
            }
        )

由上图可知,因为promise中的then方法的回调函数都是异步执行,我们需要在处理每个回调函数前加一个定时器

5.Promise构造函数以及then方法(总结)

/*
自定义promise模块: IIFE
*/
(function (window) {
    const PENDING = 'pending'
    const RESOLVED = 'resolved'
    const REJECTED = 'rejected'
    /*
    Promise构造函数
    excutor: 执行器函数(同步执行)---传入2个参数 resolve,reject
    */
    function Promise(excutor) {

        //将当前promise对象保存起来
        const self = this
        self.status = PENDING //给promise对象指定status属性,初始值为pending
        self.data = undefined  //给promise对象指定一个用于存储结果的数据的类型
        self.callbacks = []   //每个数组元素的结构: { onResolved() {}, onRejected() {}}

        function resolve(value) {
            //如果当前状态不是pending, 直接结束
            if (self.status !== PENDING) {
                return
            }
            //1.修改对象的状态为resolved
            self.status = RESOLVED
            //2.保存value数据
            self.data = value
            //3.如果有待执行callback函数, 立即执行回调函数onResolved
            if (self.callbacks.length > 0) {
                setTimeout(() => {// 放入队列中执行所有成功的回调
                    self.callbacks.forEach(callback => {
                        callback.onResolved(value)
                    });
                });

            }

        }
        function reject(reason) {
            //如果当前状态不是pending, 直接结束
            if (self.status !== PENDING) {
                return
            }
            //1.修改对象的状态为rejected
            self.status = REJECTED
            //2.保存value数据
            self.data = reason
            //3.如果有待执行callback函数, 立即执行回调函数onRejected
            if (self.callbacks.length > 0) {
                setTimeout(() => { // 放入队列中执行所有成功的回调
                    self.callbacks.forEach(callback => {
                        callback.onRejected(reason)
                    });
                })

            }
        }

        //立即同步执行excutor
        try {
            excutor(resolve, reject)
        } catch (error) {
            reject(error)
        }

    }

    /*
    Promise原型对象的then()
    指定成功和失败的回调函数
    返回一个新的promise
    */
    Promise.prototype.then = function (onResolved, onRejected) {

        const self = this

        //返回一个新的promise
        return new Promise((resolve, reject) => {

            /* 
            执行指定的回调函数
            根据执行的结果改变return的promise的状态/数据
            */
            function handle(callback) {
                //返回promise的结果由onResolved/onRejected执行结果决定
                // 1. 抛出异常, 返回promise的结果为失败, reason为异常
                // 2. 返回的是promise, 返回promise的结果就是这个结果
                // 3. 返回的不是promise, 返回promise为成功, value就是返回值
                try {
                    const result = callback(self.data)
                    if (result instanceof Promise) { //第二种情况,返回的是promise
                        result.then(
                            value => resolve(vlaue),
                            reason => reject(reason)
                        )
                    } else { //第三种情况,不是promise
                        resolve(result)
                    }
                } catch (error) {
                    reject(error)
                }
            }

            //根据状态调用回调函数
            if (self.status === RESOLVED) { //resolved
                // 立即异步执行成功的回调函数
                setTimeout(() => {
                    handle(onResolved)
                })

            } else if (self.status === REJECTED) { //rejected
                // 立即异步执行失败的回调函数
                setTimeout(() => {
                    handle(onRejected)
                })
            } else {  //pending
                self.callbacks.push({
                    onResolved(value) {
                        handle(onResolved)
                    },
                    onRejected(reason) {
                        handle(onRejected)
                    }
                })

            }
        })
    }

    // 向外暴露Promise函数
    window.Promise = Promise
})(window)

6.promise的相关方法的实现

 /* 
 Promise原型对象的catch()
 指定失败的回调函数
 返回一个新的promise对象
 */
    Promise.prototype.catch = function (onRejected) {
        return this.then(undefined, onRejected)
    }

 /* 
  Promise函数对象的resolve方法
  返回一个指定结果的成功的promise
  */   
  Promise.resolve = function (value) {
    // 返回一个成功/失败的promise
    return new Promise((resolve, reject) => {
      // value是promise
      if (value instanceof Promise) { // 使用value的结果作为promise的结果
        value.then(resolve, reject)
      } else { // value不是promise  => promise变为成功, 数据是value
        resolve(value)
      }
    })
  }

  /* 
  Promise函数对象的reject方法
  返回一个指定reason的失败的promise
  */
  Promise.reject = function (reason) {
    // 返回一个失败的promise
    return new Promise((resolve, reject) => {
      reject(reason)
    })
  }

   /* 
  Promise函数对象的all方法
  返回一个promise, 只有当所有proimse都成功时才成功, 否则只要有一个失败的就失败
  */
  Promise.all = function (promises) {
    // 用来保存所有成功value的数组
    const values = new Array(promises.length) 
    // 用来保存成功promise的数量
    let resolvedCount = 0
    // 返回一个新的promise
    return new Promise((resolve, reject) => {
      // 遍历promises获取每个promise的结果
      promises.forEach((p, index) => {
        Promise.resolve(p).then(
          value => {
            resolvedCount++ // 成功的数量加1
            // p成功, 将成功的vlaue保存vlaues
            // values.push(value)
            values[index] = value
            // 如果全部成功了, 将return的promise改变成功
            if (resolvedCount===promises.length) {
              resolve(values)
            }

          },
          reason => { // 只要一个失败了, return的promise就失败
            reject(reason)
          }
        )
      })
    })
  }

  /* 
  Promise函数对象的race方法
  返回一个promise, 其结果由第一个完成的promise决定
  */
  Promise.race = function (promises) {
    // 返回一个promise
    return new Promise((resolve, reject) => {
      // 遍历promises获取每个promise的结果
      promises.forEach((p, index) => {
        Promise.resolve(p).then(
          value => {// 一旦有成功了, 将return变为成功
            resolve(value)
          },
          reason => { // 一旦有失败了, 将return变为失败
            reject(reason)
          }
        )
      })
    })
  }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值