总结一下 Promise,怎么使用,如何手写 promise

Promise 概述

Promise 是 JavaScript 中的一个异步编程解决方案,它代表了一个最终可能完成(或失败)及其结果值的异步操作。Promise 有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。Promise 一旦从 pending 状态变为 fulfilled 或 rejected 状态,状态就不会再改变,即 Promise 的状态是不可逆的。

Promise 的基本使用

1. 创建 Promise

使用 new Promise(executor) 构造函数来创建一个 Promise 实例,executor 函数接受两个参数:resolvereject,它们是两个函数,由 JavaScript 引擎提供,分别用于将 Promise 的状态从 pending 变为 fulfilled 或 rejected。

javascript 复制代码
let promise = new Promise(function(resolve, reject) {
  // 异步操作
  if (/* 异步操作成功 */) {
    resolve(value); // 将 Promise 的状态从 pending 变为 fulfilled,并将结果作为参数传递
  } else {
    reject(error); // 将 Promise 的状态从 pending 变为 rejected,并将错误作为参数传递
  }
});
2. 使用 Promise

Promise 提供了 .then().catch().finally() 方法用于处理异步操作的结果或错误。

  • .then(onFulfilled, onRejected):当 Promise 变为 fulfilled 或 rejected 时,相应的函数会被调用。
  • .catch(onRejected):用于指定发生错误时的回调函数,是 .then(null, onRejected) 的语法糖。
  • .finally(onFinally):无论 Promise 最终状态如何,都会执行该函数。
javascript 复制代码
promise.then(function(value) {
  // 处理成功的情况
}).catch(function(error) {
  // 处理错误的情况
}).finally(function() {
  // 无论成功或失败都会执行
});

手写 Promise

下面是一个简化版的 Promise 实现,主要实现了基本的状态管理和 .then() 方法。

javascript 复制代码
function MyPromise(executor) {
  this.status = 'pending'; // 初始状态
  this.value = undefined; // 存放异步操作的结果
  this.reason = undefined; // 存放错误原因
  this.onFulfilledCallbacks = []; // 存放成功的回调函数
  this.onRejectedCallbacks = []; // 存放失败的回调函数

  // 更改 Promise 的状态
  function resolve(value) {
    if (this.status === 'pending') {
      this.status = 'fulfilled';
      this.value = value;
      this.onFulfilledCallbacks.forEach(fn => fn());
    }
  }

  function reject(reason) {
    if (this.status === 'pending') {
      this.status = 'rejected';
      this.reason = reason;
      this.onRejectedCallbacks.forEach(fn => fn());
    }
  }

  // 捕获 executor 执行器中的错误
  try {
    executor(resolve.bind(this), reject.bind(this));
  } catch (e) {
    reject.call(this, e);
  }

  // 实现 then 方法
  MyPromise.prototype.then = function(onFulfilled, onRejected) {
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
    onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason; };

    return new MyPromise((resolve, reject) => {
      if (this.status === 'fulfilled') {
        setTimeout(() => {
          try {
            let x = onFulfilled(this.value);
            resolvePromise(resolve, reject, x);
          } catch (e) {
            reject(e);
          }
        });
      } else if (this.status === 'rejected') {
        setTimeout(() => {
          try {
            let x = onRejected(this.reason);
            resolvePromise(resolve, reject, x);
          } catch (e) {
            reject(e);
          }
        });
      } else {
        this.onFulfilledCallbacks.push(() => {
          setTimeout(() => {
            try {
              let x = onFulfilled(this.value);
              resolvePromise(resolve, reject, x);
            } catch (e) {
              reject(e);
            }
          });
        });

        this.onRejectedCallbacks.push(() => {
          setTimeout(() => {
            try {
              let x = onRejected(this.reason);
              resolvePromise(resolve, reject, x);
            } catch (e) {
              reject(e);
            }
          });
        });
      }
    });
  };

  // 辅助函数,处理 then 或 catch 中的返回值
  function resolvePromise(resolve, reject, x) {
    // ... 省略了一些复杂的处理逻辑,如处理 x 为 Promise 的情况
    if (x !== promise2) { // 避免自引用
      if (x instanceof MyPromise) {
        x.then(resolve, reject);
      } else {
        resolve(x);
      }
    }
  }
}

注意:上面的代码是一个非常简化的版本,省略了很多重要的细节和错误处理逻辑(比如处理 x 为 Promise 的情况),以及 .catch().finally() 方法的实现。在实际应用中,Promise 的实现要复杂得多,并且需要处理各种边界情况和错误。

相关推荐
bugcome_com1 小时前
JWT 知识小课堂:从入门到精通,一文吃透 JSON Web Token
前端·json
To_OC2 小时前
写了三天 Next.js,我的 React 世界观被拆了又装回去
前端·全栈·next.js
独泪了无痕2 小时前
viewer.js 安装与配置指南:实现图片预览功能
前端·vue.js
起床学FPGA4 小时前
AI回答问题之后,会自动跳到最下面的问题
开发语言·javascript·ecmascript
Fluxart.ai4 小时前
电商商品图审核怎么自动化?规则引擎、人工复核与发布门禁
java·前端·自动化
why技术4 小时前
AI 写的文章,可能都带着手敲一遍都去不掉的“隐形水印”。
前端·人工智能·后端
愚公搬代码5 小时前
【愚公系列】《Android应用案例开发大全》016-LBS类应用掌上杭州(辅助工具类的开发)
android·前端
CodeSheep5 小时前
又一个华为天才少年,离职了!
前端·后端·程序员
kyriewen5 小时前
面试官说"打开你的AI工具"——我才发现,他考的根本不是写代码
前端·人工智能·面试
IT_陈寒6 小时前
Vue的双向绑定把我坑惨了,原来这个场景不能用
前端·人工智能·后端