手写实现 promise

手动实现Promise类

Promise 是 JavaScript 中用于处理异步操作的对象,我们可以手写实现一个符合 Promise A+ 规范的 Promise。

首先需要理解 Promise 的基本结构和功能。Promise 对象包含三种状态:pending(等待中)、fulfilled(已成功)和 rejected(已失败)。当 Promise 转换到 fulfilled 或 rejected 状态时,会把结果值或错误原因传递给 then 方法注册的回调函数。

以下是一个简单的 Promise 实现:

class CustomPromise {
  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((callback) => callback(value));
      }
    };

    const reject = (reason) => {
      if (this.state === 'pending') {
        this.state = 'rejected';
        this.reason = reason;
        this.onRejectedCallbacks.forEach((callback) => callback(reason));
      }
    };

    try {
      executor(resolve, reject);
    } catch (error) {
      reject(error);
    }
  }

  then(onFulfilled, onRejected) {
    return new CustomPromise((resolve, reject) => {
      if (this.state === 'fulfilled') {
        try {
          const value =
            typeof onFulfilled === 'function' ? onFulfilled(this.value) : this.value;
          resolve(value);
        } catch (error) {
          reject(error);
        }
      } else if (this.state === 'rejected') {
        try {
          const reason =
            typeof onRejected === 'function' ? onRejected(this.reason) : this.reason;
          reject(reason);
        } catch (error) {
          reject(error);
        }
      } else {
        this.onFulfilledCallbacks.push((value) => {
          try {
            const returnValue =
              typeof onFulfilled === 'function' ? onFulfilled(value) : value;
            resolve(returnValue);
          } catch (error) {
            reject(error);
          }
        });

        this.onRejectedCallbacks.push((reason) => {
          try {
            const returnValue =
              typeof onRejected === 'function' ? onRejected(reason) : reason;
            reject(returnValue);
          } catch (error) {
            reject(error);
          }
        });
      }
    });
  }

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

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

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

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

  static all(promises) {
    return new CustomPromise((resolve, reject) => {
      const results = Array(promises.length);
      let count = 0;

      promises.forEach((promise, index) => {
        CustomPromise.resolve(promise).then(
          (value) => {
            results[index] = value;
            count++;
            if (count === promises.length) {
              resolve(results);
            }
          },
          (reason) => {
            reject(reason);
          }
        );
      });
    });
  }

  static race(promises) {
    return new CustomPromise((resolve, reject) => {
      promises.forEach((promise) => {
        CustomPromise.resolve(promise).then(resolve, reject);
      });
    });
  }
}

这个实现中用到了构造函数、then 方法、catch 方法、finally 方法和静态方法 resolve、reject、all 和 race。在构造函数中,通过传入一个 executor 函数,创建了一个新的 CustomPromise 对象,并且在 executor 函数中调用 resolve 或 reject 来改变 CustomPromise 的状态;在 then 方法中,通过不同状态下返回值的处理,实现了链式调用。

需要注意的是,在实现中使用了数组来保存每个回调函数,因为 Promise 可能会存在多个 then 方法,当状态改变时需要执行所有的回调函数,而保存回调函数的数组也是实现 Promise 链式调用的关键。

此外,这个实现还加入了 catch 和 finally 方法,用于捕获 Promise 的错误和添加无论 Promise 状态如何都会执行的逻辑。

使用CustomPromise

首先可以创建一个新的 CustomPromise 对象,传入一个 executor 函数。executor 函数接受两个参数:resolve 和 reject,分别代表成功和失败的回调函数。当异步操作成功时,调用 resolve 方法并传入成功结果值;当异步操作失败时,调用 reject 方法并传入错误原因。

然后就可以在 CustomPromise 实例上调用 then 方法来注册处理 Promise 成功和失败的回调函数。then 方法接受两个参数:onFulfilled 和 onRejected,分别代表成功和失败的回调函数。这些回调函数会在 Promise 转换到 fulfilled 或 rejected 状态时被调用,并且会把结果值或错误原因传递给它们。

除了 then 方法,CustomPromise 类还提供了 catch 方法用于捕获 Promise 的错误,以及 finally 方法用于添加无论 Promise 状态如何都会执行的逻辑。

以下是使用 CustomPromise 处理异步操作的示例代码:

const customPromise = new CustomPromise((resolve, reject) => {
  // 异步操作
  setTimeout(() => {
    const randomNum = Math.random();

    if (randomNum > 0.5) {
      resolve('success');
    } else {
      reject('failed');
    }
  }, 1000);
});

customPromise.then(
  (value) => {
    console.log(value);
  },
  (reason) => {
    console.log(reason);
  }
);

customPromise.catch((error) => {
  console.log(error);
});

customPromise.finally(() => {
  console.log('finally');
});

在这个示例中,我们创建了一个 CustomPromise 对象来模拟异步操作。在 executor 函数中使用 setTimeout 模拟异步操作,并根据随机生成的数值来改变 CustomPromise 的状态。然后调用 then 方法、catch 方法和 finally 方法来注册处理 Promise 成功和失败的回调函数以及添加执行无论 Promise 状态如何都会执行的逻辑。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值