const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class _Promise {
constructor(exc) {
this._status = PENDING;
this._value = undefined;
this.resolveQue = [];
this.rejectQue = [];
const _resolve = (val)=> {
const run = () => {
if(this._status!==PENDING) return;
this._status = FULFILLED;
this._value = val;
while(this.resolveQue.length) {
const cb = this.resolveQue.shift();
cb(val);
}
}
setTimeOut(run)
}
const _reject = (reason)=> {
const run = () => {
if(this._status!==PENDING) return;
this._status=REJECTED;
this._value = reason;
while(this.rejectQue.length) {
const cb = this.rejectQue.shift();
cb(reason);
}
}
setTimeOut(run)
}
try {
exc(_resolve,_reject)
} catch (error) {
reject(error);
}
}
then(resolveFn,rejectFn) {
typeof resolveFn !== 'function' ? resolveFn = value => value : null
typeof rejectFn !== 'function' ? rejectFn = reason => { throw new
Error(reason instanceof Error? reason.message:reason); } : null
return new Promise((resolve,reject)=>{
const fulFn = (value) => {
try {
let x = resolveFn(value);
x instanceof _Promise ? x.then(resolve,reject) : resolve(x);
} catch (error) {
reject(error)
}
}
const rejFn = (value) => {
try {
let x = rejectFn(value);
x instanceof _Promise ? x.then(resolve,reject) : resolve(x)
} catch (error) {
reject(error)
}
}
switch(this._status)
case: PENDING
this.resolveQue.push(fulFn);
this.rejectQue.push(rejFn);
break;
case: FULFILLED
fulFn(this._value);
break;
case: REJECTED
rejFn(this._value);
break;
})
}
catch(rejectFn) {
return this.then(undefined, rejectFn);
}
all(promiseArr) {
return new Promise((resolve,reject) => {
let i = 0,
result = [];
promiseArr.forEach((p,j) => {
_Promise.resolve(p).then( res => {
if(i === promiseArr.length) resolve(result);
i++;
result[j] = res;
}, err => reject(err))
})
})
}
allSetted(promiseArr) {
return new Promise((resolve,reject) => {
let i = 0,
result = [];
promiseArr.forEach((p,j) => {
_Promise.resolve(p).then( res => {
if(i === promiseArr.length) resolve(result);
i++;
result[j] = {status: 'fulfilled', value: res};
})
.catch(err) {
if(i === promiseArr.length) resolve(result);
i++;
result[j] = {status: 'rejected', reason: err};
}
})
})
}
race(promiseArr) {
return new _Promise((resolve, reject) => {
for(let p of promiseArr) {
_Promise.resolve(p).then(res => {
resolve(res);
}, err => reject(err))
}
})
}
any(promiseArr) {
let i =0 , rejectsArr = [];
return new _Promise((resolve, reject) => {
promiseArr.forEach(p, j) {
_Promise.resolve(p).then(res => {
resolve(res);
}, err => {
i++
rejectsArr[j] = err;
if(i === promiseArr.length) reject(rejectsArr);
})
})
})
}
finally(callback) {
return this.then(value=>{
_promise.resolve(callback()).then(() => value)
},reason=> {
_Promise.resolve(callback()).then(() => { throw reason })
})
}
static resolve(value) {
if(value instanceof _Promise) return value;
return new _Promise((resolve, reject) => {
resolve(value);
})
}
}
juejin.cn/post/684490…
juejin.cn/post/702748…