chatGPT帮我学习Promise

49 阅读4分钟

20210119153816312.png

以下代码是 chatGPT 提供一 Promise 实现,帮助和加深自己的理解,阅读完可以解答;

Promise 本质上是一个对象,它有三种状态:pending(等待中)、fulfilled(已完成)和rejected(已拒绝)。当 Promise 对象被创建时,它的状态为 pending。当异步操作完成时,Promise 对象的状态会变为 fulfilled 或 rejected。

Promise 对象的实现原理是基于回调函数的。它通过传递两个回调函数来实现异步操作的处理:

  • resolve 回调函数,表示异步操作成功完成;

  • reject 回调函数,表示异步操作失败。当异步操作完成后,Promise 对象会自动调用相应的回调函数来处理结果。

  • then 方法为什么支持链式调用;

  • then 方法中的回调 return 数据会怎么样;

  • new Promise() 初始化构造时,如果报错了会怎么样;

  • 执行 Promise.resovel()会怎么样 ;

/**
* 自定义实现一个 Promise
*/
class MyPromise {
  // begin 构造函数
  constructor(executor) {
    
    // 从构造函数可以看出,Promise 本质上是一个对象 this;
    // 核心是异步 维护状态的变化,将【任务结果值】来传递给回调函数;
    // 对象包括状态:pending(等待中)、fulfilled(已完成)和rejected(已拒绝)
    // 初始状态 pending 并且状态变更后 不可逆
    this.state = 'pending';
    // 传递的值
    this.value = undefined;
    this.reason = undefined;
    
    // 当外部的异步任务调用了 resolve或者reject后,当前实例对象的状态发生了变更;
    // 如果没有回调函数接受,那么值是无法传递到外部的;
    // 因此业务需要维护 onFulfilledCallbacks和onRejectedCallbacks 接收结果输出
    
    // 回调是何时添加到 数组中的?
    // 回调是在当前实例的then方法时加入的;
    this.onFulfilledCallbacks = [];
    this.onRejectedCallbacks = [];
    
    // 闭包:提供给外部任务调用,成功时调用;让当前 this 状态变更,同时触发回调(给回调函数传递值)
    const resolve = (value) => {
      if (this.state === 'pending') {
        this.state = 'fulfilled';
        this.value = value;
        // 如果缺少此行,那么回调无法被执行,结果值 也将来 无法被外部使用;
        this.onFulfilledCallbacks.forEach((callback) => callback(this.value));
      }
    };
    // 闭包: 提供给外部任务调用,失败时调用;
    const reject = (reason) => {
      if (this.state === 'pending') {
        this.state = 'rejected';
        this.reason = reason;
        this.onRejectedCallbacks.forEach((callback) => callback(this.reason));
      }
    };
    

    /**
        new MyPromise((resolve, reject) => {
        //此处是同步代码
      });
    */
    // 同步执行代码executor,因此 new Promise的参数函数是同步函数;
    try {
      executor(resolve, reject);
    } catch (error) {
      // 执行同步代码异常时,立即更改状态
      reject(error);
    }
  }
  // end: constructor
  
  /**
  * 核心方法:提供回调方法注入,以及返回promise,支持链式调用
  */
  then(onFulfilled, onRejected) {
    // then 方法时,再次生成一个全新的 promise
    const newPromise = new MyPromise((resolve, reject) => {
      
      // 包装 value,传递到下一次then
      const handleFulfilled = (value) => {
        try {
          const result = onFulfilled(value);
          if (result instanceof MyPromise) {
            result.then(resolve, reject);
          } else {
            resolve(result);
          }
        } catch (error) {
          reject(error);
        }
      };

      const handleRejected = (reason) => {
        try {
          const result = onRejected(reason);
          if (result instanceof MyPromise) {
            result.then(resolve, reject);
          } else {
            resolve(result);
          }
        } catch (error) {
          reject(error);
        }
      };
      
      // 选择,根据当前的 this.state 状态值,触发回调或压入回调数组
      switch (this.state) {
          // 立即执行 resolve() 时
        case 'fulfilled':
          // 保持异步调用
          setTimeout(() => handleFulfilled(this.value), 0);
          break;
          // 立即执行 reject() 或者异常时
        case 'rejected':
          setTimeout(() => handleRejected(this.reason), 0);
          break;
         // 状态未更改,未决定时,将回调压入当前实例的回调数组 onFulfilledCallbacks和onRejectedCallbacks
        case 'pending':
          this.onFulfilledCallbacks.push(handleFulfilled);
          this.onRejectedCallbacks.push(handleRejected);
          break;
      }
    });
    
    // 返回一个新的promise实力,支持链式调用
    return newPromise;
  }
  // end: then
    
  // catch 相当于再执行一次 then
  catch(onRejected) {
    return this.then(null, onRejected);
  }
  
  //静态方法:resolve
  // 执行 Promise.resolve()时,生成一个新 Promise 实例,并且 决断 状态立即变更;
  static resolve(value) {
    return new MyPromise((resolve) => resolve(value));
  }
    
  // 同 resolve
  static reject(reason) {
    return new MyPromise((resolve, reject) => reject(reason));
  }

  // all 关注,全部成功 整个结果才是真的成功
  static all(promises) {
    // 合并生成一个新的 Promise 实例,是整个结果
    return new MyPromise((resolve, reject) => {
      const results = [];
      // 成功计数器
      let fulfilledCount = 0;

      promises.forEach((promise, index) => {
        promise.then((value) => {
          results[index] = value;
          fulfilledCount++;
          // 这 promises 数组中的每一个 Promise 实例 成功,返回结果的 Promise 才是成功;
          // 这就是为什么说全部成功,整个结果才是真的成功
          // 只有当每一个执行成功,此时成功计数器 等于 promises 数组长度,即任务长度
          if (fulfilledCount === promises.length) {
            resolve(results);
          }
        }, reject);
        // promises 中任意一个失败,则整个结果失败 reject
      });
    });
  }
    
  // 竞赛 关注 最早完成的 Promise 实例与 整个结果的关系,以及其他未完成的状态;
  static race(promises) {
    return new MyPromise((resolve, reject) => {
      promises.forEach((promise) => {
   // 在 Promise.race 方法中,包含多个任务(即多个 Promise 实例),当其中任意一个任务完成(即状态变为 fulfilled 或 rejected)后,整个 Promise.race 就会立即结束,并返回该任务的结果或错误。
   // 而其他未完成的任务将继续执行,但它们的结果不会影响 Promise.race 的返回值,或者说他们的值无法传递到下一步。
        promise.then(resolve, reject);
      });
    });
  }
}