c语言编程笔录

首页 >   > 笔记大全

笔记大全

JavaScript怎么实现手写promise

更新时间:2023-09-08

前言

JavaScript Promise 是一种用于异步编程的重要解决方案,在现代 JavaScript 开发中被广泛使用。Promise的特点是可以避免回调地狱(callback hell),提供更清晰和可读的代码结构,使得异步操作更加简洁和易于理解。在本文中,我们将学习手写一个简单的Promise实现。

实现 Promise 构造函数

在实现自定义的Promise之前,我们首先需要了解Promise的基本结构。Promise的构造函数需要接受一个executor函数作为参数,该函数会立即执行。executor函数接受两个参数:resolve和reject。当异步操作成功时,调用resolve方法;当异步操作失败时,调用reject方法。
function MyPromise(executor) {
  this.status = 'pending';  // 初始状态为pending
  this.value = undefined;  // 异步操作返回的结果
  this.onResolvedCallbacks = [];  // 存储成功的回调函数
  this.onRejectedCallbacks = [];  // 存储失败的回调函数

  const resolve = value => {
    if (this.status === 'pending') {
      this.status = 'fulfilled';
      this.value = value;
      this.onResolvedCallbacks.forEach(callback => callback(this.value));
    }
  };

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

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

实现 then 方法

Promise对象的 then 方法用于注册成功和失败的回调函数,并返回一个新的Promise对象,以支持链式调用。我们需要在MyPromise的原型上实现then方法,该方法接受两个参数:onFulfilled和onRejected,分别表示成功和失败的回调函数。
MyPromise.prototype.then = function(onFulfilled, onRejected) {
  onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
  onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason };

  const resolvePromise = (promise2, x, resolve, reject) => {
    if (promise2 === x) {
      return reject(new TypeError('循环引用'));
    }

    let called = false;
    if (x instanceof MyPromise) {
      if (x.status === 'pending') {
        x.then(
          value => resolvePromise(promise2, value, resolve, reject),
          reason => reject(reason)
        );
      } else {
        x.then(resolve, reject);
      }
    } else if (x != null && (typeof x === 'object' || typeof x === 'function')) {
      try {
        const then = x.then;
        if (typeof then === 'function') {
          then.call(
            x,
            value => {
              if (called) return;
              called = true;
              resolvePromise(promise2, value, resolve, reject);
            },
            reason => {
              if (called) return;
              called = true;
              reject(reason);
            }
          );
        } else {
          resolve(x);
        }
      } catch (error) {
        if (called) return;
        called = true;
        reject(error);
      }
    } else {
      resolve(x);
    }
  };

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

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

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

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

  return promise2;
};

总结

在以上代码中,我们成功实现了一个简单的Promise构造函数和then方法。尽管这只是一个最基本的实现,相比于内置的Promise来说还有很多功能是没有涵盖的,例如:Promise.all、Promise.race、Promise.catch等。但希望通过本文的介绍,你对Promise的实现原理和要点有了更深入的理解。手写Promise是提升JavaScript编程能力的一个很好的练习,你可以参考此实现并进行扩展,以深入理解Promise的各种用法和特性。