从 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,置状态和结果分别为 FULFILLED
和 object
。
所以,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,并置状态和结果分别为 REJECTED
和 reason
:
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,把 resolve
和 reject
分别传给 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 中的实现介绍完了。