总结一下 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 的实现要复杂得多,并且需要处理各种边界情况和错误。

相关推荐
colorFocus1 分钟前
都25年了,快用?.替代&&,??替代||
javascript
Asort1 分钟前
JavaScript设计模式(十八)——备忘录模式:状态保存与恢复的艺术
前端·javascript·设计模式
社恐的下水道蟑螂5 分钟前
一文吃透 JS 对象字面量:从基础用法到代理模式实践
javascript
over6976 分钟前
AI科技新闻速览自动化:使用n8n工作流打造个人AI助手
前端
一枚前端小能手10 分钟前
🔄 重学Vue之nextTick和slot - 从底层实现到实战应用的完整指南
前端·javascript·vue.js
Zyx200723 分钟前
HTML5 敲击乐(2):从静态页面到移动端适配的完整实践
前端
有意义25 分钟前
从HTML敲击乐了解开发流程
javascript
烟袅26 分钟前
JavaScript 中的 null 与 undefined:你真的搞懂它们的区别了吗?
javascript
有点笨的蛋27 分钟前
“花”点心思学代理:JavaScript中的对象与中介艺术
javascript