Promise原理理解, 手写一个Promise

本文详细介绍了Promise的基本原理,包括Promise的常见用法(如then,catch,all,race),以及Promise类的结构、构造函数和静态方法的实现。通过实例展示了如何创建、链式调用和处理Promise的不同状态。
摘要由CSDN通过智能技术生成

Promise原理理解, 手写一个Promise

1. Promis 常用情况

new Promise((resolve, reject) => {
    resolve(4111111)
  }).then(res => {
    console.log(res, "res");
  }).catch(err => {
    console.log(err, "err");
  })

  Promise.resolve(422222).then(res => {
    console.log(res, "res");
  })

  Promise.reject(433333).catch(err => {
    console.log(err, "err");
  })

  let p1 = new Promise((resolve, reject) => {
    resolve(4444444)
  })

  let p2 = new Promise((resolve, reject) => {
    resolve(4555555)
  })

  Promise.all([p1, p2]).then(ress => {
    console.log(ress, "ress");
  }).catch(err => {
    console.log(err, "err");
  })

  let p3 = new Promise((resolve, reject) => {
    reject(4666666)
  })

  let p4 = new Promise((resolve, reject) => {
    reject(4777777)
  })

  Promise.race([p3, p4]).then(res => {
    console.log(res, "res");
  }).catch(err => {
    console.log(err, "err");
  })

2. Promise 类结构

/**
 * Promise异常
 */
class PromiseError extends Error {
  constructor(message) {
    super(message);
    this.name = "(in promise)";
  }
}


// 是否纯在失败回调函数
let hasCatch = false;
class Promise {
  /**
   * 构成函数参数
   * @param (resolve, reject) => {)
   */
  constructor(executor) {

  }

  /**
   * then方法, 可传入成功的回调函数和失败的回调函数
   * @param res => {}
   * @param err => {}
   */
  then(onResolved, onRejected) {



  }

  /**
   * catch方法 可传入失败的回调函数
   * @param err => {}
   */
  catch(onRejected){

  }

  /**
   * 静态 resolve 方法  设置成功的值
   * @param result
   */
  static resolve(result){


  }

  /**
   * 静态 reject 方法  设置失败的值
   * @param result
   */
  static reject(result) {

  }

  /**
   * 静态 all 方法, 传入 promise 数组, 所有 promise 都成功时触发then的回调,
   * 或者其中一个 promise 失败, 触发 catch 回调
   * @param promises
   */
  static all(promises){

  }

  /**
   * 静态 race 方法, 传入 promise 数组, 其中 promise 状态变更时,就会触发回调
   * @param promises
   */
  static race (promises) {

  }
}

3. 构造函数

   /**
   * 构成函数参数
   * @param (resolve, reject) => {)
   */
  constructor(executor) {
    // pending 初始, fulfilled 成功, rejected 失败
    this.PromiseState = 'pending';
    // resolve 或 reject 函数设置的设置的返回值
    this.PromiseResult = null

    // 声明一个数组,用来存放then方法中的回调
    this.callbacks = []

    /**
     * resolve 方法,传入一个值, 调用成功回调
     * @param data
     */
    let resolve = (data) => {
      // 判断状态, 如果不是初始, 则直接 return
      if (this.PromiseState != 'pending') return
      // 状态改为成功
      this.PromiseState = 'fulfilled';
      // 赋值回调函数的返回值
      this.PromiseResult = data;
      // 异步调用回调函数,用setTimeout模拟异步
      setTimeout(() => {
        this.callbacks.forEach(item => {
          item.onResolved(data);
        })
      })
    }

    /**
     * reject 方法,传入一个值, 调用失败回调
     * @param data
     */
    let reject = (data) => {
      // 判断状态, 如果不是初始, 则直接 return
      if (this.PromiseState != 'pending') return
      // 状态改为失败
      this.PromiseState = 'rejected';
      // 赋值回调函数的返回值
      this.PromiseResult = data;
      // 异步调用回调函数,用setTimeout模拟异步
      setTimeout(() => {
        // 判断是否存在失败回调,存在则执行回调,不存在则抛异常
        if (hasCatch) {
          this.callbacks.forEach(item => {
            item.onRejected(data);
          })
        } else {
          hasCatch = true
          throw new PromiseError(data);

        }

      })
    }

    // 执行传入的函数
    try {
      executor(resolve, reject)
    } catch (err) {
      reject(err);
    }
  }

4. then 函数

  /**
   * then方法, 可传入成功的回调函数和失败的回调函数
   * @param res => {}
   * @param err => {}
   */
  then(onResolved, onRejected) {

    // 判断 onResolved 是否是函数,如果不是函数,则改为函数
    if (typeof onResolved !== 'function') {
      onResolved = value => value
    }

    if(onRejected){
      hasCatch = true;
    }

    // 判断 onRejected 是否是函数,如果不是函数,则改为函数
    if (typeof onRejected !== 'function') {
      onRejected = reason => {
        throw reason
      }
    }

    // 返回 一个 promise 对象
    return new Promise((resolve, reject) => {
      // 回调函数调用
      let callback = (callFn) => {
        try {
          // 调用回调函数
          let result = callFn(this.PromiseResult);
          // 判断返回值是否是 promise 对象
          if(result instanceof Promise){
            result.then(res => {
              resolve(res)
            }).catch(err => {
              reject(err)
            })
          }else {
            resolve(result)
          }
        }catch (err) {
          reject(err);
        }

      }

      // 判断状态, 如果是成功, 则将调用成功回调函数
      if (this.PromiseState == 'fulfilled') {
        setTimeout(() => {
          callback(onResolved);
        })
      }

      // 判断状态, 如果是失败, 则将调用失败回调函数
      if (this.PromiseState == 'rejected') {
        setTimeout(() => {
          callback(onRejected);
        })
      }

      // 判断状态, 如果是初始, 则将回调函数插入回调函数数组
      if (this.PromiseState == 'pending') {
        this.callbacks.push({
          onResolved() {
            callback(onResolved);
          }, onRejected() {
            callback(onRejected);
          }
        })
      }
    })
  }

5. catch 函数

  /**
   * catch方法 可传入失败的回调函数
   * @param err => {}
   */
  catch(onRejected) {
    // 直接调用then函数
    return  this.then(undefined, onRejected)
  }

6. then 和 catch 调用结果

6.1. then

在这里插入图片描述在这里插入图片描述

6.2. catch

在这里插入图片描述在这里插入图片描述

7. resolve函数

  /**
   * 静态 resolve 方法  设置成功的值
   * @param result
   */
  static resolve(result) {
    return new Promise((resolve, reject) => {
      if(result instanceof Promise){
        result.then(res => {
          resolve(res)
        }).catch(err => {
          reject(result);
        })
      }else {
        resolve(result);
      }
    })
  }

7.1 resolve 使用

在这里插入图片描述
在这里插入图片描述

8 reject 函数

  /**
   * 静态 reject 方法  设置失败的值
   * @param result
   */
  static reject(result) {
    return new Promise((resolve, reject) => {
      reject(result);
    })
  }

8.1 reject 函数使用

在这里插入图片描述在这里插入图片描述

9. all 函数

  /**
   * 静态 all 方法, 传入 promise 数组, 所有 promise 都成功时触发then的回调,
   * 或者其中一个 promise 失败, 触发 catch 回调
   * @param promisess
   */
  static all(promisess) {
    return new Promise((resolve, reject) => {
      // 回调触发次数
      let count = 0;
      // 对调返回参数数组
      let results = [];
      promisess.forEach(item => {
        item.then(res => {
          results.push(res);
          count ++;
          if(count >= promisess.length){
            resolve(results)
          }
        }).catch(err => {
          reject(err)
        })
      })
    })
  }

9.1. all 函数使用

都是 resolve
在这里插入图片描述
在这里插入图片描述

包含 reject
在这里插入图片描述
在这里插入图片描述

10. race 函数

  /**
   * 静态 race 方法, 传入 promise 数组, 其中 promise 状态变更时,就会触发回调
   * @param promisess
   */
  static race(promisess) {
    return new Promise((resolve, reject) => {
      promisess.forEach(item => {
        item.then(res => {
          resolve(res)
        }).catch(err => {
          reject(err)
        })
      })
    })
  }
}

10.1. race 函数使用

在这里插入图片描述在这里插入图片描述

11. 完整的代码

/**
 * Promise异常
 */
class PromiseError extends Error {
  constructor(message) {
    super(message);
    this.name = "(in promise)";
  }
}

// 是否纯在失败回调函数
let hasCatch = false;

class Promise {
  /**
   * 构成函数参数
   * @param (resolve, reject) => {)
   */
  constructor(executor) {
    // pending 初始, fulfilled 成功, rejected 失败
    this.PromiseState = 'pending';
    // resolve 或 reject 函数设置的设置的返回值
    this.PromiseResult = null

    // 声明一个数组,用来存放then方法中的回调
    this.callbacks = []

    /**
     * resolve 方法,传入一个值, 调用成功回调
     * @param data
     */
    let resolve = (data) => {
      // 判断状态, 如果不是初始, 则直接 return
      if (this.PromiseState != 'pending') return
      // 状态改为成功
      this.PromiseState = 'fulfilled';
      // 赋值回调函数的返回值
      this.PromiseResult = data;
      // 异步调用回调函数,用setTimeout模拟异步
      setTimeout(() => {
        this.callbacks.forEach(item => {
          item.onResolved(data);
        })
      })
    }

    /**
     * reject 方法,传入一个值, 调用失败回调
     * @param data
     */
    let reject = (data) => {
      // 判断状态, 如果不是初始, 则直接 return
      if (this.PromiseState != 'pending') return
      // 状态改为失败
      this.PromiseState = 'rejected';
      // 赋值回调函数的返回值
      this.PromiseResult = data;
      // 异步调用回调函数,用setTimeout模拟异步
      setTimeout(() => {
        // 判断是否存在失败回调,存在则执行回调,不存在则抛异常
        if (hasCatch) {
          this.callbacks.forEach(item => {
            item.onRejected(data);
          })
        } else {
          hasCatch = true
          throw new PromiseError(data);

        }

      })
    }

    // 执行传入的函数
    try {
      executor(resolve, reject)
    } catch (err) {
      reject(err);
    }
  }

  /**
   * then方法, 可传入成功的回调函数和失败的回调函数
   * @param res => {}
   * @param err => {}
   */
  then(onResolved, onRejected) {

    // 判断 onResolved 是否是函数,如果不是函数,则改为函数
    if (typeof onResolved !== 'function') {
      onResolved = value => value
    }

    if(onRejected){
      hasCatch = true;
    }

    // 判断 onRejected 是否是函数,如果不是函数,则改为函数
    if (typeof onRejected !== 'function') {
      onRejected = reason => {
        throw reason
      }
    }

    // 返回 一个 promise 对象
    return new Promise((resolve, reject) => {
      // 回调函数调用
      let callback = (callFn) => {
        try {
          // 调用回调函数
          let result = callFn(this.PromiseResult);
          // 判断返回值是否是 promise 对象
          if(result instanceof Promise){
            result.then(res => {
              resolve(res)
            }).catch(err => {
              reject(err)
            })
          }else {
            resolve(result)
          }
        }catch (err) {
          reject(err);
        }

      }

      // 判断状态, 如果是成功, 则将调用成功回调函数
      if (this.PromiseState == 'fulfilled') {
        setTimeout(() => {
          callback(onResolved);
        })
      }

      // 判断状态, 如果是失败, 则将调用失败回调函数
      if (this.PromiseState == 'rejected') {
        setTimeout(() => {
          callback(onRejected);
        })
      }

      // 判断状态, 如果是初始, 则将回调函数插入回调函数数组
      if (this.PromiseState == 'pending') {
        this.callbacks.push({
          onResolved() {
            callback(onResolved);
          }, onRejected() {
            callback(onRejected);
          }
        })
      }

    })

  }

  /**
   * catch方法 可传入失败的回调函数
   * @param err => {}
   */
  catch(onRejected) {
    // 直接调用then函数
    return  this.then(undefined, onRejected)
  }

  /**
   * 静态 resolve 方法  设置成功的值
   * @param result
   */
  static resolve(result) {
    return new Promise((resolve, reject) => {
      if(result instanceof Promise){
        result.then(res => {
          resolve(res)
        }).catch(err => {
          reject(result);
        })
      }else {
        resolve(result);
      }
    })
  }

  /**
   * 静态 reject 方法  设置失败的值
   * @param result
   */
  static reject(result) {
    return new Promise((resolve, reject) => {
      reject(result);
    })
  }

  /**
   * 静态 all 方法, 传入 promise 数组, 所有 promise 都成功时触发then的回调,
   * 或者其中一个 promise 失败, 触发 catch 回调
   * @param promisess
   */
  static all(promisess) {
    return new Promise((resolve, reject) => {
      // 回调触发次数
      let count = 0;
      // 对调返回参数数组
      let results = [];
      promisess.forEach(item => {
        item.then(res => {
          results.push(res);
          count ++;
          if(count >= promisess.length){
            resolve(results)
          }
        }).catch(err => {
          reject(err)
        })
      })
    })
  }

  /**
   * 静态 race 方法, 传入 promise 数组, 其中 promise 状态变更时,就会触发回调
   * @param promisess
   */
  static race(promisess) {
    return new Promise((resolve, reject) => {
      promisess.forEach(item => {
        item.then(res => {
          resolve(res)
        }).catch(err => {
          reject(err)
        })
      })
    })
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
很高兴为您提供一个手写Promise 实现,代码如下: class Promise { constructor(executor) { this.state = 'pending'; this.value = undefined; this.reason = undefined; this.onResolvedCallbacks = []; this.onRejectedCallbacks = []; const resolve = (value) => { if (this.state === 'pending') { this.state = 'fulfilled'; this.value = value; this.onResolvedCallbacks.forEach((fn) => fn()); } }; const reject = (reason) => { if (this.state === 'pending') { this.state = 'rejected'; this.reason = reason; this.onRejectedCallbacks.forEach((fn) => fn()); } }; try { executor(resolve, reject); } catch (error) { reject(error); } } then(onFulfilled, onRejected) { onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (value) => value; onRejected = typeof onRejected === 'function' ? onRejected : (reason) => { throw reason }; const promise2 = new Promise((resolve, reject) => { if (this.state === 'fulfilled') { setTimeout(() => { try { const x = onFulfilled(this.value); Promise.resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, 0); } if (this.state === 'rejected') { setTimeout(() => { try { const x = onRejected(this.reason); Promise.resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, 0); } if (this.state === 'pending') { this.onResolvedCallbacks.push(() => { setTimeout(() => { try { const x = onFulfilled(this.value); Promise.resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, 0); }); this.onRejectedCallbacks.push(() => { setTimeout(() => { try { const x = onRejected(this.reason); Promise.resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, 0); }); } }); return promise2; } static resolvePromise(promise2, x, resolve, reject) { if (promise2 === x) { return reject(new TypeError('Chaining cycle detected for promise')); } let called = false; if (x instanceof Promise) { x.then((value) => { Promise.resolvePromise(promise2, value, resolve, reject); }, reject); } else if (x !== null && (typeof x === 'object' || typeof x === 'function')) { try { const then = x.then; if (typeof then === 'function') { then.call(x, (value) => { if (called) return; called = true; Promise.resolvePromise(promise2, value, resolve, reject); }, (reason) => { if (called) return; called = true; reject(reason); }); } else { resolve(x); } } catch (error) { if (called) return; called = true; reject(error); } } else { resolve(x); } } }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值