yshaojun / blog

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

从 es6-prommise 看 Proimse 的实现(二)

yshaojun opened this issue · comments

接上文。除了实例方法,Promise 还提供了常用的4个挂载在构造函数上的函数。

5. Proimse.resolve

通常用来生成一个 FULFILLED 状态的 Promise:

export default function resolve(object) {
  /*jshint validthis:true */
  let Constructor = this;

  if (object && typeof object === 'object' && object.constructor === Constructor) {
    return object;
  }

  let promise = new Constructor(noop);
  _resolve(promise, object);
  return promise;
}

由代码可以看出,如果参数是一个 Promise 实例,则返回这个实例,否则返回一个新的 Promise,置状态和结果分别为 FULFILLEDobject

所以,Promise.resolve 会返回一个 REJECTED 状态的 Promise 么?答案是可能的:

const p = Promise.resolve(Promise.reject('rejec
p.catch((...args) => console.log(111, ...args)) // output: 111 rejected

6. Promise.reject

这个就简单了,返回一个新的 Promise,并置状态和结果分别为 REJECTEDreason

export default function reject(reason) {
  /*jshint validthis:true */
  let Constructor = this;
  let promise = new Constructor(noop);
  _reject(promise, reason);
  return promise;
}

7. Promise.all

用了一个 Enumerator 类来计数所有 Promise 返回:

export default function all(entries) {
  return new Enumerator(this, entries).promise;
}

Enumerator 实现的比较复杂,比较重要的在这里:

_settledAt(state, i, value) {
  let { promise } = this;

  if (promise._state === PENDING) {
    this._remaining--;

    if (state === REJECTED) {
      reject(promise, value);
    } else {
      this._result[i] = value;
    }
  }

  if (this._remaining === 0) {
    fulfill(promise, this._result);
  }
}

字面意思即 “状态稳定在 i”,每个 Promise 状态稳定时(状态非 PENDING),会调用这个函数将结果放到 this._result[i] 里,如果是 REJECTED 则直接 reject。这也印证了如果有一个 Promise reject,则 all 函数返回 REJECTED 的 Promise。

其实不太明白为啥整这么复杂,为什么不定义个长度相等的数组,当某个 Promise resolve 时,将结果放到数组里,并检查是不是所有结果都返回了,如果都返回了就 resolve,这样实现呢?此处同样欢迎讨论

8. Promise.race

这个实现就没那么 all 那么绕了,构造一个新的 Promise,把 resolvereject 分别传给 entries 即可,第一个非 PENDING Promise 拥有设置构造的 Promise 状态的权利:

export default function race(entries) {
  /*jshint validthis:true */
  let Constructor = this;

  if (!isArray(entries)) {
    return new Constructor((_, reject) => reject(new TypeError('You must pass an array to race.')));
  } else {
    return new Constructor((resolve, reject) => {
      let length = entries.length;
      for (let i = 0; i < length; i++) {
        Constructor.resolve(entries[i]).then(resolve, reject);
      }
    });
  }
}

以上,Promise 在 es6-promise 中的实现介绍完了。