美文网首页
手写Promise,帮助你理解Promise的内部实现原理

手写Promise,帮助你理解Promise的内部实现原理

作者: 望月从良glh | 来源:发表于2020-06-20 16:06 被阅读0次

原生Promise底层是系统底层实现的微任务,我们通过代码无法实现,只能模拟宏任务去实现

  /* 手写Promise */
const PENDING = 'padding';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
  status = PENDING;
  value = undefined;
  reason = undefined;
  successCallback = [];
  failCallback = [];
  constructor(executor) {
    try {
      executor(this.resolve, this.reject);
    } catch (e) {
      this.reject(e);
    }
  }
  resolve = value => {
    if (this.status !== PENDING) return;
    this.status = FULFILLED;
    this.value = value;
    while (this.successCallback.length) {
      this.successCallback.shift()();
    }
  };
  reject = reason => {
    if (this.status !== PENDING) return;
    this.status = REJECTED;
    this.reason = reason;
    while (this.failCallback.length) {
      this.failCallback.shift()();
    }
  };
  then(
    successCallback = value => value,
    failCallback = reason => {
      throw reason;
    }
  ) {
    let promiseThen = new MyPromise((resolve, reject) => {
      const commonCallback = callback => {
        setTimeout(() => {
          try {
            let thenResult = commonCallback(this.value);
            resolvePromise(promiseThen, thenResult, resolve, reject);
          } catch (e) {
            reject(e);
          }
        }, 0);
      };
      if (this.status === FULFILLED) {
        commonCallback(successCallback);
      } else if (this.status === REJECTED) {
        commonCallback(failCallback);
      } else {
        this.successCallback = [
          ...this.successCallback,
          () => {
            commonCallback(successCallback);
          },
        ];
        this.failCallback = [
          ...this.failCallback,
          () => {
            commonCallback(failCallback);
          },
        ];
      }
    });
    return promiseThen;
  }
  catch(failCallback) {
    return this.then(undefined, failCallback);
  }
  finally(callback) {
    return this.then(
      value => {
        return MyPromise.resolve(callback()).then(() => value);
      },
      reason => {
        return MyPromise.resolve(callback()).then(() => {
          throw reason;
        });
      }
    );
  }
  static all(array) {
    let result = [];
    let order = 0;
    return new MyPromise((resolve, reject) => {
      const addData = (key, value) => {
        result[key] = value;
        order++;
        if (order === array.length) {
          resolve(result);
        }
      };
      array.forEach((current, index) => {
        if (current instanceof MyPromise) {
          current.then(
            value => addData(index, value),
            reason => reject(reason)
          );
        } else {
          addData(index, current);
        }
      });
    });
  }
  static race(array) {
    return new MyPromise((resolve, reject) => {
      array.forEach(current => {
        let value = current;
        if (!(value instanceof MyPromise)) {
          value = MyPromise.resolve(value);
        }
        value.then(
          value => resolve(value),
          reason => reject(reason)
        );
      });
    });
  }
  static allSettled(array) {
    let result = [];
    let order = 0;
    return new MyPromise(resolve => {
      const addData = (key, value) => {
        result[key] = value;
        order++;
        if (order === array.length) {
          resolve(result);
        }
      };
      array.forEach((current, index) => {
        if (current instanceof MyPromise) {
          current.then(
            value => addData(index, value),
            reason => addData(index, reason)
          );
        } else {
          addData(index, current);
        }
      });
    });
  }
  static any(array) {
    let result = [];
    let order = 0;
    return new MyPromise((resolve, reject) => {
      function addData(key, value) {
        result[key] = value;
        order++;
        if (order === array.length) {
          reject(result);
        }
      }
      array.forEach((current, index) => {
        if (current instanceof MyPromise) {
          current.then(
            value => resolve(value),
            reason => addData(index, reason)
          );
        } else {
          resolve(value);
        }
      });
    });
  }
  static resolve(value) {
    if (value instanceof MyPromise) return value;
    return new MyPromise(resolve => resolve(value));
  }
  static reject(value) {
    return new MyPromise((resolve, reject) => reject(value));
  }
  static try(fn) {
    return new MyPromise(resolve => resolve(fn()));
  }
}

function resolvePromise(promiseThen, value, resolve, reject) {
  if (promiseThen === value) {
    return reject(
      new TypeError('Chaining cycle detected for promise #<Promise>')
    );
  }
  if (value instanceof MyPromise) {
    value.then(resolve, reject);
  } else {
    resolve(value);
  }
}

相关文章

网友评论

      本文标题:手写Promise,帮助你理解Promise的内部实现原理

      本文链接:https://www.haomeiwen.com/subject/rgxgxktx.html