```javascript
class MyPromise {
static PENDING = 'pending'
static FULLFILLED = 'fullfilled'
static REJECTED = 'rejected'
constructor(fn) {
this.status = 'pending'
this.result = null
this.resolveCbs = []
this.rejectCbs = []
try {
fn(this.resolve.bind(this), this.reject.bind(this))
} catch (e) {
this.reject(e)
}
}
resolve(d) {
setTimeout(_ => {
if (this.status === MyPromise.PENDING) {
this.status = MyPromise.FULLFILLED
this.result = d
}
while (this.resolveCbs.length) this.resolveCbs.shift()()
})
}
reject(e) {
setTimeout(_ => {
if (this.status === MyPromise.PENDING) {
this.status = MyPromise.REJECTED
this.result = e
}
while (this.rejectCbs.length) this.rejectCbs.shift()()
})
}
then(onFullfilled, onRejected) {
return new MyPromise((resolve, reject) => {
if (this.status === MyPromise.PEDNING) {
this.resolveCbs.push(onFullfilled)
this.rejectCbs.push(onRejected)
}
if (this.status === MyPromise.REJECTED) {
onFullfilled(this.result);
}
if (this.status === MyPromise.REJECTED) {
onRejected(this.result);
}
})
}
catch(e) {
return new MyPromise((resolve, reject) => {
reject(e)
})
}
static resolve(val) {
if (arg instanceof MyPromise) return val
return new MyPromise(resolve => resolve(val))
}
static all(iterator) {
return new MyPromise((resolve, reject) => {
const iter = Array.from(iterator)
let len = count = iter.length
const promises = []
try {
for (let i = 0; i < len; i++) {
count--
MyPromise.resolve(iter[i]).then(res => {
promises.push(res)
}, err => {
promises.push(err)
})
if (count === 0) {
resolve(promises)
}
}
} catch (e) {
reject(new Error(`${count}-${e}`))
}
})
}
static race(iterator) {
return new MyPromise((resolve, reject) => {
const arr = Array.from(iterator)
const len = arr.length
try {
for (let i = 0; i < len; i++) {
MyPromise.resolve(arr[i]).then(res => {
resolve(res)
})
}
} catch (e) {
reject(new Error(`${count}-${e}`))
}
})
}
static finally(promise) {
return new MyPromise((resolve, reject) => {
MyPromise.resolve(promise).then(res => resolve(res)).catch(e => reject(e))
})
}
}
const p1 = new MyPromise((resolve, reject) => {
resolve(true)
// reject(false)
})
const p2 = new MyPromise((resolve, reject) => {
resolve(true)
// reject(false)
})
p.then(res => {
}, err => {
})
// MyPromise.all(, mp2).then(res => {
// [res1, res2, ...]
// }, err => {
// })