/**
* @description MyPromise
* @author TsingYi
*/

class MyPromise {
state = 'pending' //状态,'pending', fulfilled','rejected'
value = undefined //成功后的值
reason = undefined //失败后的原因

resolveCallbacks = [] //pending状态下,储存成功的回调
rejectCallbacks = [] //pending状态下,储存失败的回调

constructor(fn) {
const resolveHandler = (value) => {
this.state = this.state === 'pending' ? 'fulfilled' : this.state
this.value = value
this.resolveCallbacks.forEach((fn) => fn(this.value))
}
const rejectHandler = (reason) => {
this.state = this.state === 'pending' ? 'rejected' : this.state
this.reason = reason
this.rejectCallbacks.forEach((fn) => fn(this.reason))
}

try {
fn(resolveHandler, rejectHandler)
} catch (err) {
rejectHandler(err)
}
}
then(fn1, fn2) {
fn1 = typeof fn1 === 'function' ? fn1 : (v) => v
fn2 =
typeof fn2 === 'function'
? fn2
: (err) => {
throw err
}

if (this.state === 'pending') {
const p = new MyPromise((resolve, reject) => {
this.resolveCallbacks.push(() => {
try {
const newValue = fn1(this.value)
resolve(newValue)
} catch (err) {
reject(err)
}
})
this.rejectCallbacks.push(() => {
try {
const newReason = fn2(this.reason)
resolve(newReason)
} catch (err) {
reject(err)
}
})
})
return p
}
if (this.state === 'fulfilled') {
const p = new MyPromise((resolve, reject) => {
try {
const newValue = fn1(this.value)
resolve(newValue)
} catch (err) {
reject(err)
}
})
return p
}
if (this.state === 'rejected') {
const p = new MyPromise((resolve, reject) => {
try {
const newReason = fn2(this.reason)
resolve(newReason)
} catch (err) {
reject(err)
}
})
return p
}
}
catch(fn) {
return this.then(null, fn)
}
}

const p1 = new MyPromise((resolve, reject) => {
resolve(100)
// reject('err123')
// setTimeout(() => {
// resolve(100)
// }, 500)
// setTimeout(() => {
// reject('err123')
// }, 500)
})
p1.then((data1) => {
console.log('data1', data1)
return data1 + 2
})
.catch((err2) => {
console.error(err2)
return err2 + 4
})
.then((data3) => {
console.log('data3', data3)
return data3
})