手写promise ,实现 then ,catch,finally,resolve,reject,all,allSettled

完整代码

原生Promise 的用法

1.Promise 是 JavaScript 中用于处理异步操作的重要工具。它代表了一个异步操作的最终完成或失败,并且使异步方法可以像同步方法那样返回值。

  • resolve:当异步操作成功时调用的函数,用于将 Promise 的状态改为 fulfilled,并将结果值传递给后续的 .then() 方法。
  • reject:当异步操作失败时调用的函数,用于将 Promise 的状态改为 rejected,并将错误原因传递给后续的 .catch() 方法。
javascript 复制代码
const myPromise = new Promise((resolve, reject) => {
  // 模拟异步操作,比如网络请求或文件读取
  setTimeout(() => {
    const success = true; // 假设操作成功
    if (success) {
      resolve('操作成功');
    } else {
      reject('操作失败');
    }
  }, 1000);
});

2. 使用 .then() 和 .catch()

  • then():用于处理 Promise 成功时的回调函数。
  • catch():用于处理 Promise 失败时的回调函数。
javascript 复制代码
myPromise
  .then((value) => {
    console.log(value); // 输出: 操作成功
  })
  .catch((error) => {
    console.error(error); // 如果 Promise 被拒绝,这里会输出错误
  });

3.使用 .finally().

  • .finally():无论 Promise 成功还是失败,都会执行的回调函数,通常用于清理工作。
javascript 复制代码
myPromise
  .then((value) => {
    console.log(value);
  })
  .catch((error) => {
    console.error(error);
  })
  .finally(() => {
    console.log('无论成功还是失败,都会执行这里');
  });

4.静态方法

1. Promise.all()

  • Promise.all():等待所有 Promise 都成功后,返回一个包含所有结果的数组。如果有一个 Promise 失败,则立即拒绝。
javascript 复制代码
const promise1 = Promise.resolve(1);
const promise2 = Promise.resolve(2);
const promise3 = Promise.resolve(3);

Promise.all([promise1, promise2, promise3])
  .then((values) => {
    console.log(values); // 输出: [1, 2, 3]
  })
  .catch((error) => {
    console.error(error);
  });

2. Promise.race()

  • Promise.race():返回第一个完成的 Promise 的结果,无论是成功还是失败。
javascript 复制代码
const promise1 = new Promise((resolve) => setTimeout(resolve, 1000, '1'));
const promise2 = new Promise((resolve) => setTimeout(resolve, 500, '2'));

Promise.race([promise1, promise2])
  .then((value) => {
    console.log(value); // 输出: 2(因为 promise2 先完成)
  })
  .catch((error) => {
    console.error(error);
  });

3.Promise.allSettled()

  • Promise.allSettled():等待所有 Promise 都完成,无论成功还是失败,返回一个包含每个 Promise 状态和结果的数组。
javascript 复制代码
const promise1 = Promise.resolve(1);
const promise2 = Promise.reject(2);
const promise3 = Promise.resolve(3);

Promise.allSettled([promise1, promise2, promise3])
  .then((results) => {
    console.log(results);
    // 输出:
    // [
    //   { status: 'fulfilled', value: 1 },
    //   { status: 'rejected', reason: 2 },
    //   { status: 'fulfilled', value: 3 }
    // ]
  });

4.Promise.any()

  • Promise.any():返回第一个成功完成的 Promise 的结果。如果所有 Promise 都失败,则返回一个包含所有错误的 AggregateError。
javascript 复制代码
const promise1 = Promise.reject(1);
const promise2 = Promise.reject(2);
const promise3 = Promise.resolve(3);

Promise.any([promise1, promise2, promise3])
  .then((value) => {
    console.log(value); // 输出: 3
  })
  .catch((errors) => {
    console.error(errors);
  });

手写promise 完整代码

scss 复制代码
const PROMISE_STATUS_PENDING = "pending";// Promise 状态:进行中
const PROMISE_STATUS_FULFILLED = "fulfilled";// Promise 状态:已成功
const PROMISE_STATUS_REJECTED = "rejected";// Promise 状态:已失败

/**
 * 执行函数并捕获错误
 * @param {Function} fn - 要执行的函数
 * @param {any} value - 函数的参数
 * @param {Function} resolve - 成功回调
 * @param {Function} reject - 失败回调
 */


function execWithCatch(fn, value, resolve, reject) {
  try {
    const result = fn(value);
    resolve(result);
  } catch (error) {
    reject(error);
  }
}
/**
 * SmPromise 类,模拟原生 Promise 的行为
 */
class SmPromise {
    /**
   * 创建一个 SmPromise 实例
   * @param {Function} executor - 执行器函数,接收 resolve 和 reject 作为参数
   */
  constructor(exector) {
    this.status = PROMISE_STATUS_PENDING; // 初始状态为 pending
    this.value = undefined; // 成功时的值
    this.reason = undefined; // 失败时的原因
    this.onFulfilledCallbacks = []; // 存储成功回调的数组
    this.onRejectedCallbacks = []; // 存储失败回调的数组
      /**
     * 解决 Promise 的方法
     * @param {any} value - Promise 成功的值
     */
    const resolve = (value) => {
      if (this.status == PROMISE_STATUS_PENDING) {
         // 如果当前状态是 pending
        queueMicrotask(() => {
         // 使用微任务确保异步执行
          if (this.status != PROMISE_STATUS_PENDING) return; // 如果状态已改变,直接返回
          this.status = PROMISE_STATUS_FULFILLED; // 改变状态为 fulfilled
          this.value = value; // 设置成功值
          // 执行所有存储的成功回调
          this.onFulfilledCallbacks.forEach((callback) => {
            callback(this.value);
          });
        });
      }
    };
     /**
     * 拒绝 Promise 的方法
     * @param {any} reason - Promise 失败的原因
     */
    const reject = (value) => {
      if (this.status == PROMISE_STATUS_PENDING) {
        queueMicrotask(() => {
          if (this.status != PROMISE_STATUS_PENDING) return;
          this.status = PROMISE_STATUS_REJECTED;  // 改变状态为 rejected
          this.reason = value; // 设置失败原因
           // 执行所有存储的失败回调
          this.onRejectedCallbacks.forEach((callback) => {
            callback(this.reason);
          });
        });
      }
    };
    try {
     // 执行用户传入的执行器函数
      exector(resolve, reject);
    } catch (error) {
     // 如果执行器函数抛出异常,调用 reject 处理
      reject(error);
    }
  }
   /**
   * Promise 链式调用方法
   * @param {Function} onFulfilled - 成功时的回调函数
   * @param {Function} onRejected - 失败时的回调函数
   * @returns {SmPromise} 返回一个新的 SmPromise 实例
   */
  then(onFulfilled, onRejected) {
   // 设置默认的成功回调,如果没有传入则返回原值
   const defaultOnFulfilled = (value) => value;
    // 设置默认的失败回调,如果没有传入则抛出错误
   const defaultOnRejected = (err) => { throw err;};
    // 如果用户没有传入回调函数,则使用默认值
    onRejected = onRejected ?? defaultOnRejected;
    onFulfilled = onFulfilled ?? defaultOnFulfilled;
        // 返回一个新的 Promise
    return new SmPromise((resolve, reject) => {
      /**
       * 处理成功回调的函数
       */
      const handleFulfilled = () => {
        // 执行回调函数,并处理结果
        execWithCatch(onFulfilled, this.value, resolve, reject);
      };

      /**
       * 处理失败回调的函数
       */
      const handleRejected = () => {
        // 执行回调函数,并处理结果
        execWithCatch(onRejected, this.reason, resolve, reject);
      };

     // 根据当前 Promise 的状态,执行相应的处理函数
      if (this.status === PROMISE_STATUS_FULFILLED && onFulfilled) {
        // execWithCatch(onFulfilled, this.value, resolve, reject);
        handleFulfilled()
      }
      if (this.status === PROMISE_STATUS_REJECTED && onRejected) {
        handleRejected()
      }
        // 如果当前状态是 pending,将回调存储起来,等待状态改变后再执行
      if (this.status === PROMISE_STATUS_PENDING) {
        if (onFulfilled)
            this.onFulfilledCallbacks.push(handleFulfilled);
        if (onRejected)
            this.onRejectedCallbacks.push(handleRejected);
      }
    });
  }
  /**
   * 捕获 Promise 链中的错误
   * @param {Function} onRejected - 错误处理函数
   * @returns {SmPromise} 返回一个新的 SmPromise 实例
   */
  catch(onRejected) {
    // catch 等价于 then(undefined, onRejected)
    return this.then(undefined, onRejected);
  }
 /**
   * 无论 Promise 成功还是失败都会执行的回调
   * @param {Function} onFinally - 最终执行的回调函数
   * @returns {SmPromise} 返回一个新的 SmPromise 实例
   */
  finally(onFinally) {
    this.then(
      () => {
        onFinally();
      },
      () => {
        onFinally();
      }
    );
  }
  /**
   * 静态方法,返回一个已解决的 Promise
   * @param {any} value - Promise 的值
   * @returns {SmPromise} 返回一个已解决的 SmPromise 实例
   */
  static resolve(value) {
    return new SmPromise((resove) => resove(value));
  }
 /**
   * 静态方法,返回一个已拒绝的 Promise
   * @param {any} reason - Promise 拒绝的原因
   * @returns {SmPromise} 返回一个已拒绝的 SmPromise 实例
   */
  static reject(reason) {
    return new SmPromise((resolve, reject) => reject(reason));
  }
    /**
   * 静态方法,等待所有 Promise 完成
   * @param {Array} promises - Promise 数组
   * @returns {SmPromise} 返回一个新的 SmPromise 实例
   */
  static all(promises) {
    return new SmPromise((resolve, reject) => {
      const allPrimiseResult = []; // 存储所有 Promise 的结果
      promises.forEach((promise) => {
        promise.then(
          (res) => {
            allPrimiseResult.push(res);
               // 如果所有 Promise 都已完成,解决新的 Promise
            if (allPrimiseResult.length === promises.length) {
              resolve(allPrimiseResult);
            }
          },
          (err) => {
            reject(err); // 如果有 Promise 拒绝,新的 Promise 立即拒绝
          }
        );
      });
    });
  }
  /**
   * 静态方法,等待所有 Promise 完成,无论成功还是失败
   * @param {Array} promises - Promise 数组
   * @returns {SmPromise} 返回一个新的 SmPromise 实例
   */
  static allSettled(promises) {
    return new SmPromise((resolve, reject) => {
      const allPrimiseResult = []; // 存储每个 Promise 的状态和结果
      let completedCount = 0;   // 已完成的 Promise 数量
      promises.forEach((promise, index) => {
        SmPromise.resolve(promise)
          .then(
            (res) => {
             // 保存成功状态和结果
              allPrimiseResult[index] = {
                status: PROMISE_STATUS_FULFILLED,
                value: res,
              };
            },
            (err) => {
                  // 保存失败状态和原因
              allPrimiseResult[index] = {
                status: PROMISE_STATUS_REJECTED,
                err,
              };
            }
          )
          .then(() => {
            completedCount++;
             // 如果所有 Promise 都已完成,解决新的 Promise
            if (completedCount === promises.length) {
              resolve(results);
            }
          });
      });
    });
  }
    /**
   * 静态方法,返回第一个完成的 Promise 的结果
   * @param {Array} promises - Promise 数组
   * @returns {SmPromise} 返回一个新的 SmPromise 实例
   */
  static race(promises) {
    return new SmPromise((resolve, reject) => {
         // 遍历每个 Promise,第一个完成的将决定新的 Promise 的结果
      promises.forEach((promise) => {
        // promise.then(res => {
        //   resolve(res)
        // }, err => {
        //   reject(err)
        // })
        SmPromise.resolve(promise).then(resolve, reject);
        // promise.then(resolve, reject)
      });
    });
  }
   /**
   * 静态方法,返回第一个成功完成的 Promise 的结果,如果所有都失败则返回 AggregateError
   * @param {Array} promises - Promise 数组
   * @returns {SmPromise} 返回一个新的 SmPromise 实例
   */
  static any(promises) {
    const errors = []; // 存储所有失败的原因
    return new SmPromise((reslove, reject) => {
      promise.forEach((promise) => {
        promise.then(
          (res) => {
             // 如果有 Promise 成功,新的 Promise 立即解决
            reslove(res);
          },
          (err) => {
            errors.push(err);  // 保存失败原因
            if (errors.length === promises.length) {
                 // 如果所有 Promise 都失败,新的 Promise 拒绝
              reject(new AggregateError(errors));
            }
          }
        );
      });
    });
  }
}
相关推荐
浪遏33 分钟前
我的远程实习(二) | git 持续更新版
前端
智商不在服务器1 小时前
XSS 绕过分析:一次循环与两次循环的区别
前端·xss
_Matthew1 小时前
JavaScript |(四)正则表达式 | 尚硅谷JavaScript基础&实战
开发语言·javascript·正则表达式
MonkeyKing_sunyuhua1 小时前
npm WARN EBADENGINE required: { node: ‘>=14‘ }
前端·npm·node.js
Hi-Jimmy1 小时前
【VolView】纯前端实现CT三维重建-CBCT
前端·架构·volview·cbct
janthinasnail2 小时前
编写一个简单的chrome截图扩展
前端·chrome
拉不动的猪2 小时前
刷刷题40(vue中计算属性不能异步,如何实现异步)
前端·javascript·vue.js
冴羽yayujs2 小时前
SvelteKit 最新中文文档教程(6)—— 状态管理
前端·javascript·vue.js·前端框架·react·svelte·sveltekit
烛阴3 小时前
前端进阶必学:JavaScript Class 的正确打开方式,让你代码更清晰!
前端·javascript
乐闻x3 小时前
如何创建HTML自定义元素:使用 Web Component 的最佳实践
前端·html·web component