当前位置:首页 > JavaScript

promise js 实现

2026-01-31 21:01:51JavaScript

Promise 实现原理

Promise 是 JavaScript 中处理异步操作的一种机制,其核心是通过状态管理、回调队列和链式调用来实现异步流程控制。以下是实现一个简易 Promise 的关键步骤:

基本结构

Promise 包含三种状态:pendingfulfilledrejected。初始状态为 pending,最终会转变为 fulfilledrejected

class MyPromise {
  constructor(executor) {
    this.state = 'pending';
    this.value = undefined;
    this.reason = undefined;
    this.onFulfilledCallbacks = [];
    this.onRejectedCallbacks = [];

    const resolve = (value) => {
      if (this.state === 'pending') {
        this.state = 'fulfilled';
        this.value = value;
        this.onFulfilledCallbacks.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 方法实现

then 方法接收两个回调函数 onFulfilledonRejected,并返回一个新的 Promise 以实现链式调用。

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

resolvePromise 函数

处理 then 方法返回的值,确保符合 Promise 规范(如处理嵌套 Promise 或 thenable 对象)。

function resolvePromise(promise2, x, resolve, reject) {
  if (promise2 === x) {
    return reject(new TypeError('Chaining cycle detected'));
  }
  let called = false;
  if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
    try {
      const then = x.then;
      if (typeof then === 'function') {
        then.call(
          x,
          y => {
            if (called) return;
            called = true;
            resolvePromise(promise2, y, resolve, reject);
          },
          r => {
            if (called) return;
            called = true;
            reject(r);
          }
        );
      } else {
        resolve(x);
      }
    } catch (e) {
      if (called) return;
      called = true;
      reject(e);
    }
  } else {
    resolve(x);
  }
}

其他方法扩展

实现 catchfinally 和静态方法(如 Promise.resolvePromise.all)。

promise js 实现

catch(onRejected) {
  return this.then(null, onRejected);
}

finally(callback) {
  return this.then(
    value => MyPromise.resolve(callback()).then(() => value),
    reason => MyPromise.resolve(callback()).then(() => { throw reason; })
  );
}

static resolve(value) {
  return new MyPromise(resolve => resolve(value));
}

static reject(reason) {
  return new MyPromise((_, reject) => reject(reason));
}

static all(promises) {
  return new MyPromise((resolve, reject) => {
    const results = [];
    let count = 0;
    promises.forEach((p, i) => {
      p.then(
        value => {
          results[i] = value;
          count++;
          if (count === promises.length) resolve(results);
        },
        reject
      );
    });
  });
}

注意事项

  1. 异步执行then 的回调需要通过 setTimeout 或微任务队列(如 queueMicrotask)异步执行,确保执行顺序符合规范。
  2. 错误处理:构造函数和 then 方法中的错误需通过 reject 捕获。
  3. 链式调用:每次调用 then 返回一个新的 Promise,避免状态污染。

以上实现简化了部分边界情况(如中止 Promise 链),但覆盖了核心功能。实际应用中建议直接使用原生 Promise 或成熟的库(如 Bluebird)。

标签: promisejs
分享给朋友:

相关文章

js实现拖拽

js实现拖拽

实现拖拽的基本步骤 通过监听鼠标事件(mousedown、mousemove、mouseup)实现拖拽功能。以下是核心代码逻辑: const draggableElement = document.…

原生js实现轮播图

原生js实现轮播图

基本结构搭建 HTML部分需要包含轮播图容器、图片列表及导航按钮。结构示例如下: <div class="slider-container"> <div class="slid…

js实现类

js实现类

JavaScript 实现类的几种方式 JavaScript 是一种基于原型的语言,但在 ES6 之后引入了 class 语法糖,使得实现类更加直观。以下是几种常见的实现方式: 使用构造函数 传统的…

js实现瀑布流

js实现瀑布流

实现瀑布流布局 瀑布流布局是一种常见的网页布局方式,常用于图片展示、商品列表等场景。以下是使用 JavaScript 实现瀑布流布局的几种方法。 纯 JavaScript 实现 通过计算元素的位置和…

js实现删除

js实现删除

使用 splice 方法删除数组元素 splice 方法可以删除数组中的元素,并返回被删除的元素。它接受两个参数:起始索引和要删除的元素数量。 const array = [1, 2, 3, 4…

js实现乘法

js实现乘法

实现乘法运算的方法 在JavaScript中实现乘法运算可以通过多种方式完成,以下列举几种常见方法: 基础运算符 直接使用乘法运算符*是最简单的方式: let result = 3 * 5; //…