/**
* 1. 绑定resolve reject 的this
* 2. 状态不可变
* 3. resolve reject 以第一次为准
* 4. throw 执行reject
*/
class MyPromise {
/**
*
* @param {*} executor 传进来的函数
*/
constructor(executor) {
this.initValue()
this.initBind()//1
//4
try {
executor(this.resolve, this.reject)
} catch (error) {
this.reject(error)
}
}
initValue() {
this.State = 'pending'
this.result = null
this.onFulfilledCallBacks = []
this.onRejectedCallBacks = []
}
/**
* 防止运行环境改变,resolve-this改变
*/
initBind() {
this.resolve = this.resolve.bind(this)
this.reject = this.reject.bind(this)
}
/**
* 要求pending=>fulfilled
* 只改变一次
* @param {*} value 成功是传进的值
*/
resolve(value) {
if (this.State !== 'pending') return //只改变一次 3,2
this.State = 'fulfilled'
this.result = value
//通知then 回调
while (this.onFulfilledCallBacks.length) {
this.onFulfilledCallBacks.pop()()
}
}
reject(reason) {
if (this.State !== 'pending') return //只改变一次
this.State = 'rejected'
this.result = reason
while (this.onRejectedCallBacks.length) {
this.onRejectedCallBacks.pop()()
}
}
/**
* 1. 接受两个回调函数
* 2. 定时器(异步执行)
* 3. 链式调用
* 4. then 可以被同一个promise调用多次
* 5. 微任务
* @param {fun} onFulfilled 成功回调
* @param {fun} onRejected 失败回调
*/
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val//简写参数判断
onRejected = typeof onRejected === 'function' ? onRejected : reason => reason
const thenPromise = new MyPromise((resolve, reject) => {
/**
* then 执行then 拿到他的值给下一个then使用//成功 或失败时候调用啊
* @param {*} callback then 的回调函数
*/
const resolvePromise = callback => {//绑定的是外部
setTimeout(() => {
//console.log(this)//this上一个Promise
try {
let callbackResult = callback(this.result)
if (callbackResult instanceof MyPromise) {
//执行结果就是MyPromise
callbackResult.then(resolve, reject)// 等这个Promise自己决定成功还是失败
} else {
//直接就是成功的
resolve(callbackResult)
}
} catch (error) {
//回调执行失败
reject(error)
}
})
}
if (this.State === 'fulfilled') {
resolvePromise(onFulfilled)
}
if (this.State === 'rejected') {
resolvePromise(onRejected)
}
if (this.State === 'pending') {
//缓存回调 先进先出
this.onFulfilledCallBacks.unshift(resolvePromise.bind(this, onFulfilled))
this.onRejectedCallBacks.unshift(resolvePromise.bind(this, onRejected))
}
})
return thenPromise//链式调用
}
/**
* 相当于then(null,onReject)
* @param {*} onRejected
* @returns
*/
catch(onRejected) {
return this.then(null, onRejected);
}
/**
* 指定不管 Promise 对象最后状态如何
* 回调函数不接受任何参数
* 总是会返回原来的值
* 返回的是一个
*/
finnaly(callback) {
return this.then(value => {
MyPromise.resolve(callback()).then(() => value)
}, reason => {
MyPromise.reject(callback()).then(() => { throw reason })
})
}
/**
* 静态 resolve 把一个value 变成Promise
* @param {any}
* 1. 参数是Promise 直接返回就是
* 2. new Promise 包装一下
*/
static resolve(value) {
if (value && typeof value === 'object' && value instanceof MyPromise) {
return value
}
return new MyPromise((resolve, reject) => {
resolve(value)
})
}
/**
* 返回一个新的 Promise 实例,该实例的状态为rejected
* @param {*} value
*/
static reject(value) {
return new MyPromise((resolve, reject) => {
reject(value)
})
}
/**
* 所有成功为成功,有错拒绝
* @param {*} promiseArrs promise数组
*/
static all(promiseArrs) {
let res = []//promise数组执行结果
let index = 0;
return new MyPromise(resolve, reject => {
if (promiseArrs.length) resolve([])
promiseArrs.forEach((p, i) => {
//先包一层 防止数组中有不是promise
MyPromise.resolve(p).then(
val => {
index++;
res[i] = val
if (index == promiseArrs.length) {
resolve(res)
}
},
reason => {
reject(reason)
}
)
});
})
}
/**
* 返回第一个成功或者拒绝
* @param {*} promiseArrs
* @returns
*/
static race(promiseArrs) {
return new MyPromise(resolve, reject => {
if (promiseArrs.length) resolve([])
promiseArrs.forEach((p) => {
//先包一层 防止数组中有不是promise
MyPromise.resolve(p).then(
val => {
resolve(val)
},
reason => {
reject(reason)
}
)
});
})
}
/**
* 一组异步操作都结束了,不管每一个操作是成功还是失败,再进行下一步操作
* @param {*} promiseArrs
*/
static AllSettled(promiseArrs){
let res = []//promise数组执行结果
let index = 0;
return new MyPromise(resolve, reject => {
if (promiseArrs.length) resolve([])
const fn = (status,val,i)=>{
res[i] = {
status,val
}
index++;
if(index==promiseArrs.length){
resolve(res)
}
}
promiseArrs.forEach((p, i) => {
//先包一层 防止数组中有不是promise
MyPromise.resolve(p).then(
val => {
fn("fulfilled",val,i)
},reason=>{
fn("rejected",reason,i)
}
)
});
})
}
/**
* all 相反 有成功就成功
* @param {*} promiseArrs
*/
static any(promiseArrs){
let index = 0;
let res = []
return new MyPromise((resolve,reject)=>{
if (promiseArrs.length) resolve([])
promiseArrs.forEach((p,i)=>{
MyPromise.resolve(p).then(
val=>{
resolve(val)
},reason=>{
index++;
res[i] = reason
if(index==promiseArrs.length)
{
reject(res)
}
}
)
})
})
}
}
总结
尽量和Promise+规范靠近,但是还是不足
比如 Promise 是一个微任务,但是这里用计时器
Promise.resolve 没对thenable对象处理等