手寫一個Promise(4)

前言

最後一篇,說說除了then之外的

Resolve和Reject

實現了前面的then後,這兩個方法就很簡答了。

  static resolve(value) {
    return new Eswang((resolve, reject) => {
      if (value instanceof Eswang) {
        value.then(resolve, reject);
      } else resolve(value);
    });
  }

這裏處理resolve中的Promise的方式和前面一樣。

Reject也類似:

  static reject(value) {
    return new Eswang((resolve, reject) => {
      reject(value);
    });
  }

All

先貼代碼:

static all(promises) {
    const values = [];
    return new Eswang((resolve, reject) => {
      promises.forEach(promise => {
        promise.then(
          value => {
            values.push(value);
            if (values.length === promises.length) resolve(values);
          },
          reason => {
            reject(reason);
          }
        );
      });
    });
  }

這裏爲了判斷所有的promise都成功,使用了數組長度和傳入的Promises長度的比較。

同時只要有一個失敗,reject就會執行。

race

因爲狀態改變不能覆蓋的特性,所以race實現起來相當簡單:

  static race(promises) {
    return new Eswang((resolve, reject) => {
      promises.map(promise => {
        promise.then(
          value => {
            resolve(value);
          },
          reason => {
            reject(reason);
          }
        );
      });
    });
  }

最後

貼一下全家福:

class Eswang {
  static PENDING = "pending";
  static FUFILLED = "fufillied";
  static REJECTED = "rejected";

  constructor(executor) {
    this.status = Eswang.PENDING;
    this.val = null;
    this.callbacks = [];
    try {
      executor(this.resolve.bind(this), this.reject.bind(this));
    } catch (error) {
      this.reject(error);
    }
  }

  resolve(value) {
    if (this.status === Eswang.PENDING) {
      this.status = Eswang.FUFILLED;
      this.val = value;
      setTimeout(() => {
        this.callbacks.map(callback => {
          callback.onFufilled(this.val);
        });
      });
    }
  }
  reject(reason) {
    if (this.status === Eswang.PENDING) {
      this.status = Eswang.REJECTED;
      this.val = reason;
      setTimeout(() => {
        this.callbacks.map(callback => {
          callback.onReject(this.val);
        });
      });
    }
  }
  then(onFufilled, onReject) {
    if (typeof onFufilled !== "function") {
      onFufilled = () => this.val;
    }
    if (typeof onReject !== "function") {
      onReject = () => this.val;
    }
    let promise = new Eswang((resolve, reject) => {
      if (this.status === Eswang.PENDING) {
        this.callbacks.push({
          onFufilled: val => {
            this.parse(promise, onFufilled(val), resolve, reject);
          },
          onReject: val => {
            this.parse(promise, onReject(val), resolve, reject);
          }
        });
      }
      if (this.status === Eswang.FUFILLED) {
        setTimeout(() => {
          this.parse(promise, onFufilled(this.val), resolve, reject);
        });
      }
      if (this.status === Eswang.REJECTED) {
        setTimeout(() => {
          this.parse(promise, onReject(this.val), resolve, reject);
        });
      }
    });
    return promise;
  }
  parse(promise, result, resolve, reject) {
    if (promise == result) {
      throw new Error("cuole");
    }
    try {
      if (result instanceof Eswang) {
        result.then(resolve, reject);
      } else resolve(result);
    } catch (error) {
      reject(error);
    }
  }

  static resolve(value) {
    return new Eswang((resolve, reject) => {
      if (value instanceof Eswang) {
        value.then(resolve, reject);
      } else resolve(value);
    });
  }
  static reject(value) {
    return new Eswang((resolve, reject) => {
      reject(value);
    });
  }
  static all(promises) {
    const values = [];
    return new Eswang((resolve, reject) => {
      promises.forEach(promise => {
        promise.then(
          value => {
            values.push(value);
            if (values.length === promises.length) resolve(values);
          },
          reason => {
            reject(reason);
          }
        );
      });
    });
  }
  static race(promises) {
    return new Eswang((resolve, reject) => {
      promises.map(promise => {
        promise.then(
          value => {
            resolve(value);
          },
          reason => {
            reject(reason);
          }
        );
      });
    });
  }
}
發佈了386 篇原創文章 · 獲贊 411 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章