/*
** TODO list: 1、then函数的REJECTED和PENDING状态 也要参考FULFILLED状态做改造
** 2、缺少resolve 和 reject的静态方法
*/
// 先定义三个常量表示状态
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
constructor(executor) {
try {
executor(this.resolve, this.reject)
}
catch(err) {
this.reject(err)
}
}
status = PENDING
value = null
reason = null
onFulfilledCbs = []
onRejectedCbs = []
resolve = (value) => {
if (this.status === PENDING) {
this.status = FULFILLED
this.value = value
while(this.onFulfilledCbs.length) {
const cb = this.onFulfilledCbs.shift()
cb && cb(value)
}
}
}
reject = (reason) => {
if (this.status === PENDING) {
this.status = REJECTED
this.reason = reason
while(this.onRejectedCbs.length) {
const cb = this.onRejectedCbs.shift()
cb && cb(reason)
}
}
}
then = (onFulfilled, onRejected) => {
// 如果不传,就使用默认函数
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw reason};
// 为了链式调用这里直接创建一个 MyPromise,并在后面 return 出去
const promise2 = new MyPromise((resolve, reject) => {
// 这里的内容在执行器中,会立即执行
if (this.status === FULFILLED) {
// 创建一个微任务等待 promise2 完成初始化
queueMicrotask(() => {
try {
// 获取成功回调函数的执行结果
const x = onFulfilled(this.value);
// 传入 resolvePromise 集中处理
resolvePromise(promise2, x, resolve, reject);
} catch (err) {
reject(err)
}
})
} else if (this.status === REJECTED) {
onRejected(this.reason);
} else if (this.status === PENDING) {
this.onFulfilledCbs.push(onFulfilled);
this.onRejectedCbs.push(onRejected);
}
})
return promise2;
}
}
function resolvePromise(promise2, x, resolve, reject) {
// 如果相等了,说明return的是自己,抛出类型错误并返回
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
// 判断x是不是 MyPromise 实例对象
if(x instanceof MyPromise) {
// 执行 x,调用 then 方法,目的是将其状态变为 fulfilled 或者 rejected
x.then(value => resolve(value), reason => reject(reason))
// 简化之后
//x.then(resolve, reject)
} else {
// 普通值
resolve(x)
}
}
// test code
const promise = new MyPromise((resolve, reject) => {
resolve('success')
// throw new Error('执行器错误')
})
// 第一个then方法中的错误要在第二个then方法中捕获到
promise.then(value => {
console.log(1)
console.log('resolve', value)
throw new Error('then error')
}, reason => {
console.log(2)
console.log(reason.message)
}).then(value => {
console.log(3)
console.log(value);
}, reason => {
console.log(4)
console.log(reason.message)
})
console