返回

手写 Promise 进阶版:深入理解异步编程的利器

前端

手写 Promise:掌握异步编程的利器

什么是 Promise?

Promise 是一种 JavaScript 对象,它代表着异步操作的最终结果,无论是成功还是失败。它允许我们编写可读且可维护的代码,轻松应对异步操作带来的复杂性。

手写 Promise 的步骤

1. 初始化 Promise

const promise = new Promise((resolve, reject) => {
  // 异步操作在这里执行
});

2. 异步调用

promise.then(result => {
  // 成功后执行的代码
}).catch(error => {
  // 失败后执行的代码
});

3. 链式调用

promise
  .then(result => {
    return '新的 Promise 结果';
  })
  .then(newResult => {
    // 处理新的 Promise 结果
  })
  .catch(error => {
    // 处理错误
  });

4. API

4.1 .resolve

Promise.resolve(value).then(value => {
  // 成功后执行的代码
});

4.2 .reject

Promise.reject(error).then(error => {
  // 失败后执行的代码
});

4.3 .all

Promise.all([promise1, promise2]).then([result1, result2] => {
  // 所有 Promise 成功后执行的代码
});

4.4 .race

Promise.race([promise1, promise2]).then(result => {
  // 第一个 Promise 成功或失败后执行的代码
});

实现 Promise API 的手写 Promise

让我们深入了解一下如何手动实现 Promise 的 API。以下是一个用 JavaScript 编写的简单实现:

class Promise {
  constructor(executor) {
    this.state = 'pending';
    this.value = undefined;
    this.error = undefined;
    this.thenCallbacks = [];
    this.catchCallbacks = [];

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

  resolve(value) {
    if (this.state !== 'pending') return;

    this.state = 'fulfilled';
    this.value = value;

    for (const callback of this.thenCallbacks) {
      callback(value);
    }
  }

  reject(error) {
    if (this.state !== 'pending') return;

    this.state = 'rejected';
    this.error = error;

    for (const callback of this.catchCallbacks) {
      callback(error);
    }
  }

  then(onFulfilled, onRejected) {
    return new Promise((resolve, reject) => {
      this.thenCallbacks.push(result => {
        try {
          const nextValue = onFulfilled ? onFulfilled(result) : result;
          resolve(nextValue);
        } catch (error) {
          reject(error);
        }
      });

      if (onRejected) {
        this.catchCallbacks.push(error => {
          try {
            const nextValue = onRejected(error);
            resolve(nextValue);
          } catch (error) {
            reject(error);
          }
        });
      }
    });
  }

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

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

  static reject(error) {
    return new Promise((resolve, reject) => {
      reject(error);
    });
  }

  static all(promises) {
    return new Promise((resolve, reject) => {
      const results = [];
      let count = 0;

      promises.forEach((promise, index) => {
        promise
          .then(result => {
            results[index] = result;
            count++;
            if (count === promises.length) {
              resolve(results);
            }
          })
          .catch(error => {
            reject(error);
          });
      });
    });
  }

  static race(promises) {
    return new Promise((resolve, reject) => {
      promises.forEach(promise => {
        promise
          .then(result => {
            resolve(result);
          })
          .catch(error => {
            reject(error);
          });
      });
    });
  }
}

代码示例

以下是一个使用手写 Promise 的示例:

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('异步操作的结果');
  }, 1000);
});

promise.then(result => {
  console.log(result); // '异步操作的结果'
});

常见问题解答

1. 为什么使用 Promise?

Promise 提供了一种清晰、可读的方式来处理异步操作,使代码更易于维护和调试。

2. .then 和 .catch 方法有什么区别?

.then 方法用于处理 Promise 成功时的结果,而 .catch 方法用于处理 Promise 失败时的错误。

3. Promise 可以嵌套吗?

是的,Promise 可以链式调用,允许我们将多个异步操作串联在一起。

4. Promise.all 和 Promise.race 方法有什么区别?

Promise.all 等待所有给定的 Promise 都解决完毕,然后返回一个包含所有结果的数组。Promise.race 则等待第一个给定的 Promise 解决完毕,然后返回该结果。

5. 如何处理拒绝的 Promise?

使用 .catch 方法来处理拒绝的 Promise 并捕获错误。

结论

手写 Promise 是一种强大的技术,可以让你充分利用异步编程的优势。通过理解其原理和实现,你可以编写更健壮、更可读的代码。