手写promise,promise原理实现

const PENDING = "pending";
const REJECTED = "rejected";
const FULFILLED = "fulfilled";
function isFunction(func) {
    
    
  return typeof func === "function";
}

function isObject(obj) {
    
    
  return typeof obj === "object" && obj !== null;
}

function resolutionProcedure(promise, x, resolve, reject) {
    
    
  if (promise === x) {
    
    
    reject(new TypeError("promise and x refer to the same object"));
    return;
  }
  if (isObject(x) || isFunction(x)) {
    
    
    try {
    
    
      let then = x.then;
      if (isFunction(then)) {
    
    
        let isCalled = false;
        try {
    
    
          then.call(
            x,
            (y) => {
    
    
              if (isCalled) {
    
    
                return;
              }
              isCalled = true;
              resolutionProcedure(promise, y, resolve, reject);
            },
            (r) => {
    
    
              if (isCalled) {
    
    
                return;
              }
              isCalled = true;
              reject(r);
            }
          );
        } catch (error) {
    
    
          if (isCalled) {
    
    
            return;
          }
          isCalled = true;
          reject(error);
        }
      } else {
    
    
        resolve(x);
      }
    } catch (error) {
    
    
      reject(error);
    }
  } else {
    
    
    resolve(x);
  }
}

class PromiseA {
    
    
  constructor(expression) {
    
    
    this.PromiseState = PENDING;
    this.PromiseResult = undefined;
    this.onFulfilledCallbacks = [];
    this.onRejectedCallbacks = [];
    let resolve = (value) => {
    
    
      if (this.PromiseState === PENDING) {
    
    
        this.PromiseState = FULFILLED;
        this.PromiseResult = value;
        this.onFulfilledCallbacks.forEach((cb) => {
    
    
          cb();
        });
      }
    };
    let reject = (reason) => {
    
    
      if (this.PromiseState === PENDING) {
    
    
        this.PromiseState = REJECTED;
        this.PromiseResult = reason;
        this.onRejectedCallbacks.forEach((cb) => {
    
    
          cb();
        });
      }
    };
    expression(resolve, reject);
  }
  then(onFulfilled, onRejected) {
    
    
    let x;
    // let [onFulfilled, onRejected] = Array.prototype.slice.call(arguments);
    if (!isFunction(onFulfilled)) {
    
    
      onFulfilled = (data) => {
    
    
        return data;
      };
    }
    if (!isFunction(onRejected)) {
    
    
      onRejected = (error) => {
    
    
        throw error;
      };
    }
    let promise2 = new PromiseA((resolve, reject) => {
    
    
      if (this.PromiseState === PENDING) {
    
    
        this.onFulfilledCallbacks.push(() => {
    
    
          setTimeout(() => {
    
    
            try {
    
    
              x = onFulfilled(this.PromiseResult);
              resolutionProcedure(promise2, x, resolve, reject);
            } catch (e) {
    
    
              reject(e);
            }
          });
        });
        this.onRejectedCallbacks.push(() => {
    
    
          setTimeout(() => {
    
    
            try {
    
    
              x = onRejected(this.PromiseResult);
              resolutionProcedure(promise2, x, resolve, reject);
            } catch (e) {
    
    
              reject(e);
            }
          });
        });
      }
      if (this.PromiseState === FULFILLED) {
    
    
        setTimeout(() => {
    
    
          try {
    
    
            x = onFulfilled(this.PromiseResult);
            resolutionProcedure(promise2, x, resolve, reject);
          } catch (e) {
    
    
            reject(e);
          }
        });
      }
      if (this.PromiseState === REJECTED) {
    
    
        setTimeout(() => {
    
    
          try {
    
    
            x = onRejected(this.PromiseResult);
            resolutionProcedure(promise2, x, resolve, reject);
          } catch (e) {
    
    
            reject(e);
          }
        });
      }
    });
    return promise2;
  }
  catch() {
    
    }
  finally() {
    
    }
}

代码测试:


let p2 = new PromiseA(function (resolve, reject) {
    
    
  console.log(2);
  setTimeout(() => {
    
    
    reject("failed");
  }, 2000);
});
console.log(3);
p2.then(
  (data) => {
    
    
    console.log("data");
    console.log(data);
  },
  (error) => {
    
    
    console.log(4);
    console.log(error);
  }
).then(
  (data) => {
    
    
    console.log("data");
    console.log(data);
  },
  (error) => {
    
    
    console.log(4);
    console.log(error);
  }
);
p2.then(
  (data) => {
    
    
    console.log(6);
    console.log(data);
  },
  (error) => {
    
    
    console.log(4);
    console.log(error);
  }
);
console.log(5);

PromiseA.defer = PromiseA.deferred = function () {
    
    
  let dfd = {
    
    };
  dfd.promise = new PromiseA((resolve, reject) => {
    
    
    dfd.resolve = resolve;
    dfd.reject = reject;
  });
  return dfd;
};

猜你喜欢

转载自blog.csdn.net/weixin_43595755/article/details/118272286