深入promise

147 阅读1分钟

three mutually exclusive states:

  • fulfilled
  • rejected
  • pending

firstly,pending

settled这个知道就行,解释不使用这个,以免混淆。

A promise is said to be settled if it is not pending, i.e. if it is either fulfilled or rejected.
settled === fulfilled/rejected

resolved & unresolved

image.png

A promise is resolved if it is settled or if it has been “locked in” to match the state of another promise An unresolved promise is always in the pending state. A resolved promise may be pending, fulfilled or rejected.

未解决的承诺始终处于挂起状态(pending)。已解决的承诺可能处于待定、履行或拒绝状态。

  • unresolved : pending
  • resolved: pending, fulfilled or rejected

如果将立即将p.then(f, r)排队以调用函数,则fulfilled/rejected。

以下是一个更复杂的 Promise 实现,包含了一些常见的用法和特性:

class Promise {
  constructor(executor) {
    this.state = 'pending';
    this.value = null;
    this.handlers = [];

    if (typeof executor !== 'function') {
      throw new TypeError('executor must be a function');
    }

    this.executor = executor;
  }

  then(onFulfilled, onRejected) {
    if (this.state === 'pending') {
      const next = new Promise((resolve, reject) => {
        this.handlers.push((result) => {
          if (typeof onFulfilled === 'function' && result !== null) {
            try {
              resolve(onFulfilled(result));
            } catch (e) {
              reject(e);
            }
          } else {
            resolve(result);
          }
        });
      });

      this.executor((result) => {
        this.handlers.forEach((handler) => handler(result));
      });

      return next;
    } else if (this.state === 'fulfilled' && typeof onFulfilled === 'function') {
      return Promise.resolve(onFulfilled(this.value)).then(resolve => resolve(this.value));
    } else if (this.state === 'rejected' && typeof onRejected === 'function') {
      return Promise.resolve(onRejected(this.value)).then(resolve => resolve(this.value));
    } else {
      return this;
    }
  }

  catch(onRejected) {
    return this.then(() => Promise.reject(this.value), onRejected);
  }

  finally(onFinally) {
    const promise = new Promise((resolve, reject) => {
      let isRejected = false;
      let result = null;
      let value = null;
      let error = null;

      const handler = (...args) => {
        if (args[0] instanceof Error) {
          error = args[0];
          isRejected = true;
        } else {
          result = args[0];
        }
        resolve();
      };

      this.then(handler, (...args) => {
        if (args[0] instanceof Error) {
          error = args[0];
          isRejected = true;
        } else {
          result = args[0];
        }
        resolve();
      });
      onFinally();
      if (isRejected) {
        reject(error);
      } else {
        resolve(result);
      }
    });
    return promise;
  }
}