当前位置:首页 > JavaScript

js原生实现promise

2026-02-02 20:06:57JavaScript

实现 Promise 的基本结构

Promise 是异步编程的一种解决方案,原生实现需要遵循 Promise/A+ 规范。以下是一个基础的 Promise 实现框架:

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 方法是 Promise 的核心,用于添加成功和失败的回调:

then(onFulfilled, onRejected) {
  onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
  onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason };

  const promise2 = new MyPromise((resolve, reject) => {
    if (this.state === 'fulfilled') {
      setTimeout(() => {
        try {
          const x = onFulfilled(this.value);
          resolvePromise(promise2, x, resolve, reject);
        } catch (error) {
          reject(error);
        }
      }, 0);
    }

    if (this.state === 'rejected') {
      setTimeout(() => {
        try {
          const x = onRejected(this.reason);
          resolvePromise(promise2, x, resolve, reject);
        } catch (error) {
          reject(error);
        }
      }, 0);
    }

    if (this.state === 'pending') {
      this.onFulfilledCallbacks.push(() => {
        setTimeout(() => {
          try {
            const x = onFulfilled(this.value);
            resolvePromise(promise2, x, resolve, reject);
          } catch (error) {
            reject(error);
          }
        }, 0);
      });

      this.onRejectedCallbacks.push(() => {
        setTimeout(() => {
          try {
            const x = onRejected(this.reason);
            resolvePromise(promise2, x, resolve, reject);
          } catch (error) {
            reject(error);
          }
        }, 0);
      });
    }
  });

  return promise2;
}

实现 resolvePromise 函数

resolvePromise 用于处理 then 方法返回的值,确保符合 Promise 的链式调用规范:

function resolvePromise(promise2, x, resolve, reject) {
  if (promise2 === x) {
    return reject(new TypeError('Chaining cycle detected for promise'));
  }

  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 (error) {
      if (called) return;
      called = true;
      reject(error);
    }
  } else {
    resolve(x);
  }
}

实现 catch 方法

catch 方法是 then 方法的语法糖,专门用于捕获错误:

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

实现静态方法

Promise 还提供了一些静态方法,如 resolve、reject 和 all:

js原生实现promise

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

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

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

注意事项

  • 异步执行:Promise 的回调函数需要通过 setTimeout 或其他方式确保异步执行。
  • 错误处理:构造函数和 then 方法中都需要捕获可能的错误。
  • 链式调用:then 方法需要返回一个新的 Promise 以实现链式调用。
  • 值穿透:当 then 的参数不是函数时,需要实现值穿透功能。

以上代码实现了一个基本的 Promise,符合 Promise/A+ 规范的核心功能。实际应用中可能还需要实现更多功能如 finally、race 等方法。

标签: jspromise
分享给朋友:

相关文章

js实现轮播图

js实现轮播图

轮播图实现方法 基础HTML结构 <div class="slider"> <div class="slides"> <img src="image1.jpg…

js实现日历

js实现日历

实现日历的基本思路 使用JavaScript实现日历的核心是动态生成日期表格,并处理月份切换逻辑。需要计算当前月的天数、起始星期几,并动态渲染到页面上。 获取当前日期信息 通过Date对象获取当前年…

js轮播图实现原理

js轮播图实现原理

轮播图的基本原理 轮播图通过动态切换显示的内容(图片、文本等)实现视觉上的滑动效果。核心原理是利用CSS和JavaScript控制元素的显示与隐藏,或通过变换位置实现滑动动画。 实现方法一:…

js实现延迟

js实现延迟

实现延迟的方法 在JavaScript中,实现延迟操作有多种方式,以下是几种常见的方法: 使用setTimeout函数 setTimeout是JavaScript中最常用的延迟执行方法。它接受一个回…

vue promise实现同步

vue promise实现同步

在Vue中实现同步操作通常需要借助Promise或async/await来处理异步代码的同步化执行。以下是几种常见的方法: 使用async/await简化异步流程 在Vue的methods或生命周期…

js实现文字滚动

js实现文字滚动

实现文字滚动的几种方法 使用CSS动画实现滚动 通过CSS的@keyframes和transform属性可以实现平滑的文字滚动效果。 <style> .scroll-text { w…