const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class VPromise {
constructor(excutor) {
this.status = PENDING
this.value = undefined
this.fulfilledQueues = []
this.rejectedQueues = []
try {
excutor(this._resolve, this._reject)
} catch (e) {
this._reject(e)
}
}
_resolve = value => {
const run = () => {
if (this.status === PENDING) {
if (value instanceof VPromise) {
value.then(res => {
this.status = FULFILLED
this.value = value
let cb
while (cb = this.fulfilledQueues.shift()) {
cb(res)
}
}, err => {
this.status = REJECTED
this.value = err
let cb
while (cb = this.rejectedQueues.shift()) {
cb(err)
}
})
} else {
this.status = FULFILLED
this.value = value
let cb
while (cb = this.fulfilledQueues.shift()) {
cb(value)
}
}
}
}
setTimeout(() => run(), 0)
}
_reject = reason => {
const run = () => {
if (this.status === PENDING) {
this.status = REJECTED
this.value = reason
let cb
while (cb = this.rejectedQueues.shift()) {
cb(reason)
}
}
}
setTimeout(() => run(), 0)
}
then(onFulfilled, onRejected) {
const { status, value, fulfilledQueues, rejectedQueues } = this
return new VPromise((_resolveNext, _rejectNext) => {
let resolve = val => {
try {
if (typeof onFulfilled !== 'function') {
_resolveNext(val)
} else {
let x = onFulfilled(val)
if (x instanceof VPromise) {
// 执行x,成功则调用
x.then(_resolveNext, _rejectNext)
} else {
_resolveNext(x)
}
}
} catch (e) {
_rejectNext(e)
}
}
let reject = val => {
try {
if (typeof onRejected !== 'function') {
_rejectNext(val)
} else {
let x = onRejected(val)
if (x instanceof VPromise) {
// 执行x,成功则调用
x.then(_resolveNext, _rejectNext)
} else {
_resolveNext(x)
}
}
} catch (e) {
_rejectNext(e)
}
}
if (status === FULFILLED) {
resolve(value)
}
if (status === REJECTED) {
reject(value)
}
// 执行器是异步的情况,把回调放到回调队列里
if (status === PENDING) {
fulfilledQueues.push(resolve)
rejectedQueues.push(reject)
}
})
}
catch(onRejected) {
return this.then(undefined, onRejected)
}
finally(onFinally) {
return this.then(
value => VPromise.resolve(onFinally()).then(() => value),
reason => VPromise.resolve(onFinally()).then(() => { throw reason })
);
};
static resolve(value) {
if (value instanceof VPromise) return value
return new VPromise(resolve => resolve(value))
}
static reject(value) {
return new VPromise((resolve, reject) => reject(value))
}
static all(list) {
return new VPromise((resolve, reject) => {
let values = []
let count = 0
for (let [i, value] of list.entries()) {
this.resolve(value).then(res => {
values.push(res)
count += 1
if (count === list.length) resolve(values)
}, err => {
reject(err)
})
}
})
}
static race(list) {
return new VPromise((resolve, reject) => {
for (let value of list) {
this.resolve(value).then(res => {
resolve(res)
}, err => {
reject(err)
})
}
})
}
}
VPromise.resolve(3).then((values) => {
}, err => {
});
Promise.resolve(3).finally(() => {
})
console