【每日一题】实现一个简单的Promise

112 阅读3分钟

题目:实现一个简单的Promise

要求:

  1. 设计一个Promise类,具备基本的Promise功能,包括then方法和catch方法。
  2. Promise应该支持异步操作。
  3. 可以考虑Promise的链式调用。

以下是可能的起点,但可以根据需要进行修改:

class MyPromise {
  constructor(executor) {
    // 实现你的Promise构造函数
  }

  then(onFulfilled, onRejected) {
    // 实现你的then方法
  }

  catch(onRejected) {
    // 实现你的catch方法
  }
}

// 示例
const promise = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    const randomNumber = Math.random();
    if (randomNumber > 0.5) {
      resolve('Success');
    } else {
      reject('Failure');
    }
  }, 1000);
});

promise
  .then((result) => {
    console.log('Resolved:', result);
    return 'New Value';
  })
  .then((result) => {
    console.log('Chained Resolved:', result);
  })
  .catch((error) => {
    console.error('Rejected:', error);
  });

请完善 MyPromise 类,确保它能够正确处理异步操作和链式调用。

74d801682d4f401e9f3e90944bd4b616_3.png

class MyPromise {
  constructor(executor) {
    // Promise 状态,初始为 pending
    this.state = 'pending';
    // Promise 结果值
    this.value = undefined;
    // 存储异步处理函数的数组
    this.handlers = [];

    // Promise 成功时的回调
    const resolve = (value) => {
      // 只有在状态为 pending 时才能改变状态
      if (this.state === 'pending') {
        // 将状态改为 fulfilled
        this.state = 'fulfilled';
        // 存储结果值
        this.value = value;
        // 执行所有成功回调函数
        this.handlers.forEach((handler) => handler.onFulfilled(value));
      }
    };

    // Promise 失败时的回调
    const reject = (reason) => {
      // 只有在状态为 pending 时才能改变状态
      if (this.state === 'pending') {
        // 将状态改为 rejected
        this.state = 'rejected';
        // 存储失败原因
        this.value = reason;
        // 执行所有失败回调函数
        this.handlers.forEach((handler) => handler.onRejected(reason));
      }
    };

    try {
      // 执行用户传入的执行函数,并传入 resolve 和 reject
      executor(resolve, reject);
    } catch (error) {
      // 如果执行函数抛出异常,直接调用 reject 处理异常
      reject(error);
    }
  }

  then(onFulfilled, onRejected) {
    // 返回一个新的 Promise 对象
    return new MyPromise((resolve, reject) => {
      // 处理异步操作的通用函数
      const handle = (handler) => {
        try {
          // 执行处理函数,并获取返回值
          const result = handler(this.value);
          // 根据返回值的类型进行处理
          if (result instanceof MyPromise) {
            // 如果返回值是 Promise 对象,递归调用 then 方法
            result.then(resolve, reject);
          } else {
            // 否则直接将返回值作为新 Promise 的结果值
            resolve(result);
          }
        } catch (error) {
          // 如果执行处理函数时抛出异常,调用 reject 处理异常
          reject(error);
        }
      };

      if (this.state === 'fulfilled') {
        // 如果当前 Promise 已经是 fulfilled 状态,直接处理成功回调
        handle(onFulfilled);
      } else if (this.state === 'rejected') {
        // 如果当前 Promise 已经是 rejected 状态,直接处理失败回调
        handle(onRejected);
      } else if (this.state === 'pending') {
        // 如果当前 Promise 还是 pending 状态,将回调函数存入数组等待后续处理
        this.handlers.push({
          onFulfilled: (value) => handle(onFulfilled),
          onRejected: (reason) => handle(onRejected),
        });
      }
    });
  }

  catch(onRejected) {
    // catch 方法实际上是 then 方法的语法糖,直接调用 then 并传入 undefined 作为成功回调
    return this.then(undefined, onRejected);
  }
}

// 示例
const promise = new MyPromise((resolve, reject) => {
  // 模拟异步操作,1 秒后随机决定是成功还是失败
  setTimeout(() => {
    const randomNumber = Math.random();
    if (randomNumber > 0.5) {
      resolve('Success');
    } else {
      reject('Failure');
    }
  }, 1000);
});

// 链式调用 then 方法
promise
  .then((result) => {
    console.log('Resolved:', result);
    // 返回一个新值,作为后续 then 方法的参数
    return 'New Value';
  })
  .then((result) => {
    console.log('Chained Resolved:', result);
  })
  // 捕获异常
  .catch((error) => {
    console.error('Rejected:', error);
  });

这个实现中,注释详细解释了每个部分的作用,包括 Promise 的状态切换、异步操作的处理、链式调用的实现等。请注意,实际中的 Promise 还有很多细节需要处理,这里为了简化示例可能会省略一些边界情况。