// promise 状态
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
const isFn = fn => typeof fn === 'function';
class Promise {
constructor(resolver) {
if (!isFn(resolver)) {
throw new TypeError('Promise 参数必须是函数');
}
//状态和值
this._status = PENDING;
this._value;
//执行队列
this._fulfilledQueue = [];
this._rejectedQueue = [];
//绑定this
this._resolve = this._resolve.bind(this);
this._reject = this._reject.bind(this);
resolver(this._resolve, this._reject);
}
_resolve(val) {
if (this._status !== PENDING) return;
//因为Promise里面的函数是同步的,then是异步的
setTimeout(() => {
this._status = FULFILLED;
this._value = val;
let cb;
while (cb = this._fulfilledQueue.shift()) {
cb(this._value)
}
}, 0);
}
_reject(val) {
if (this._status !== PENDING) return;
//因为Promise里面的函数是同步的,then是异步的
setTimeout(() => {
this._status = REJECTED;
this._value = val;
let cb;
while (cb = this._rejectedQueue.shift()) {
cb(this._value)
}
}, 0);
}
// then 参数类型:
//(1)值
//(2)函数, 返回值或者Promise
then(onFulfilled, onRejected) {
return new Promise((resolve, reject) => {
// 返回一个 resolve 或者 reject 函数
let runThen = (callback, resolver) => {
return function (val) {
try {
if (!isFn(callback)) { // 判断 onFulfilled、onRejected 是否是一个 function,否的话直接透传value
resolver(val)
} else {
const res = callback(val); // 判断函数返回值是否是一个 Promise
if (res instanceof Promise) {
res.then(resolve, reject);
} else {
resolver(res)
}
}
} catch (err) {
reject(err);
}
}
}
//判断当前的status
switch (this._status) {
case FULFILLED:
runThen(onFulfilled, resolve)(this._value);
break;
case REJECTED:
runThen(onRejected, reject)(this._value);
break;
case PENDING: //状态未变,将函数添加到执行队列,等待状态改变后执行
this._fulfilledQueue.push(runThen(onFulfilled, resolve));
this._rejectedQueue.push(runThen(onRejected, reject));
break;
}
});
}
static resolve(promise) {
// 判断 promise 是否是一个 promise 对象
if (promise instanceof Promise) {
return promise;
} else {
return new Promise(resolve => {
resolve(promise);
});
}
}
static reject(err){
return new Promise((resolve, reject) => reject(err));
}
catch(onRejected) {
return this.then(undefined, onRejected);
}
finally(callback) {
return this.then(
value => Promise.resolve(callback()).then(() => value),
reason => Promise.resolve(callback()).then(() => { throw reason })
);
}
static race(pmList) {
return new Promise((resolve, reject) => {
pmList.forEach(item => {
// item 可能不是 promise,所以先调用 promise.resolve
Promise.resolve(item).then(val => {
resolve(val);
}, err => {
reject(err);
});
})
})
}
static all(pmList) {
return new Promise((resolve, reject) => {
let resolveArr = [];
let count = 0;
pmList.forEach((item, index) => {
// item 可能不是 promise,所以先调用 promise.resolve
Promise.resolve(item).then(val => {
resolveArr[index] = val;
count++;
if (count === pmList.length) {
resolve(resolveArr);
}
}, err => {
reject(err);
});
})
})
}
}