Promise是JavaScript中的异步编程解决方案,可以避免回调地狱,使代码更加清晰易读。下面是一个手写的Promise实现:

class Promise {
  constructor(executor) {
    this.status = 'pending'; // Promise状态,初始为pending
    this.value = undefined; // Promise的值,初始为undefined
    this.reason = undefined; // Promise的原因,初始为undefined
    this.onResolvedCallbacks = []; // Promise resolve时的回调函数列表
    this.onRejectedCallbacks = []; // Promise reject时的回调函数列表

    // 定义resolve函数,将Promise状态改为resolved并执行回调函数列表
    const resolve = (value) => {
      if (this.status === 'pending') {
        this.value = value;
        this.status = 'resolved';
        this.onResolvedCallbacks.forEach(fn => fn());
      }
    }

    // 定义reject函数,将Promise状态改为rejected并执行回调函数列表
    const reject = (reason) => {
      if (this.status === 'pending') {
        this.reason = reason;
        this.status = 'rejected';
        this.onRejectedCallbacks.forEach(fn => fn());
      }
    }

    // 执行executor函数,并传入resolve和reject函数
    try {
      executor(resolve, reject);
    } catch (error) {
      reject(error);
    }
  }

  // 定义then方法,返回一个新的Promise实例
  then(onResolved, onRejected) {
    // 如果onResolved不是函数,则将其替换成返回输入值的函数
    onResolved = typeof onResolved === 'function' ? onResolved : value => value;
    // 如果onRejected不是函数,则将其替换成抛出输入错误的函数
    onRejected = typeof onRejected === 'function' ? onRejected : error => { throw error };

    // 定义新的Promise实例
    const promise2 = new Promise((resolve, reject) => {
      if (this.status === 'resolved') {
        // 如果当前Promise状态为resolved,则执行onResolved函数,并将返回值作为新的Promise值
        setTimeout(() => {
          try {
            const x = onResolved(this.value);
            resolvePromise(promise2, x, resolve, reject);
          } catch (error) {
            reject(error);
          }
        }, 0);
      } else if (this.status === 'rejected') {
        // 如果当前Promise状态为rejected,则执行onRejected函数,并将返回值作为新的Promise值
        setTimeout(() => {
          try {
            const x = onRejected(this.reason);
            resolvePromise(promise2, x, resolve, reject);
          } catch (error) {
            reject(error);
          }
        }, 0);
      } else {
        // 如果当前Promise状态为pending,则将回调函数加入回调函数列表
        this.onResolvedCallbacks.push(() => {
          setTimeout(() => {
            try {
              const x = onResolved(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);
        });
      }
    });

    // 返回新的Promise实例
    return promise2;
  }

  // 定义catch方法,返回一个新的Promise实例
  catch(onRejected) {
    return this.then(null, onRejected);
  }

  // 定义静态resolve方法,返回一个resolved状态的Promise实例
  static resolve(value) {
    return new Promise(resolve => {
      resolve(value);
    });
  }

  // 定义静态reject方法,返回一个rejected状态的Promise实例
  static reject(reason) {
    return new Promise((resolve, reject) => {
      reject(reason);
    });
  }

  // 定义静态all方法,返回一个新的Promise实例,当所有Promise实例都为resolved时,返回所有Promise实例的值组成的数组;当有一个Promise实例为rejected时,返回该Promise实例的原因
  static all(promises) {
    return new Promise((resolve, reject) => {
      const values = [];
      let count = 0;
      for (let i = 0; i < promises.length; i++) {
        Promise.resolve(promises[i]).then(value => {
          values[i] = value;
          count++;
          if (count === promises.length) {
            resolve(values);
          }
        }, reason => {
          reject(reason);
        });
      }
    });
  }

  // 定义静态race方法,返回一个新的Promise实例,当有一个Promise实例状态改变时,返回该Promise实例的值或原因
  static race(promises) {
    return new Promise((resolve, reject) => {
      for (let i = 0; i < promises.length; i++) {
        Promise.resolve(promises[i]).then(value => {
          resolve(value);
        }, reason => {
          reject(reason);
        });
      }
    });
  }
}

// 定义resolvePromise函数,用于处理then方法返回的值和新的Promise实例的关系
function resolvePromise(promise, x, resolve, reject) {
  if (promise === x) {
    reject(new TypeError('Chaining cycle detected for promise'));
  } else if (x instanceof Promise) {
    x.then(
      value => {
        resolvePromise(promise, value, resolve, reject);
      },
      reason => {
        reject(reason);
      }
    );
  } else if (typeof x === 'object' || typeof x === 'function') {
    if (x === null) {
      resolve(x);
    }
    let then = null;
    try {
      then = x.then;
    } catch (error) {
      reject(error);
    }
    if (typeof then === 'function') {
      let called = false;
      try {
        then.call(
          x,
          value => {
            if (called) {
              return;
            }
            called = true;
            resolvePromise(promise, value, resolve, reject);
          },
          reason => {
            if (called) {
              return;
            }
            called = true;
            reject(reason);
          }
        );
      } catch (error) {
        if (called) {
          return;
        }
        called = true;
        reject(error);
      }
    } else {
      resolve(x);
    }
  } else {
    resolve(x);
  }
}
手写一个promise

原文地址: https://www.cveoy.top/t/topic/ZUL 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录