目录
构建MyPromise基础类
首先需要构建一个MyPromise类
class MyPromise {
constructor(executor) {
this.initBind()
this.initValue()
try {
executor(this.resolve, this.reject);
} catch (e) {
this.reject(e)
}
}
initValue() {
this.PromiseState = "pending"
this.PromiseResult = null;
this.onFulfilledCallbacks = []; // 保存成功的回调
this.onRejectedCallbacks = []; // 保存失败的回调
}
initBind() {
this.resolve = this.resolve.bind(this)
this.reject = this.reject.bind(this)
}
resolve(value) {
if(this.PromiseState !=="pending") return
this.PromiseResult = value;
this.PromiseState = "fulfilled"
while(this.onFulfilledCallbacks.length) {
let resolveFun = this.onFulfilledCallbacks.shift();
resolveFun(this.PromiseResult)
}
}
reject(reason) {
if(this.PromiseState !=="pending") return
this.PromiseResult = reason;
this.PromiseState = "rejected"
while(this.onRejectedCallbacks.length) {
let rejectFun = this.onRejectedCallbacks.shift();
rejectFun(this.PromiseResult)
}
}
}
实现Promise的then方法
这个方法接受两个函数类型的参数,分别是成功和失败的回调函数
MyPromise.prototype.then = function(onFulfilled, onRejected) {
let state = this.PromiseState;
// 首先校验这两个参数是不是一个函数
onFulfilled = typeof onFulfilled === "function" ? onFulfilled : val => val
onRejected = typeof onRejected === "function" ? onRejected : reason => { throw reason }
if(state === "fulfilled") {
// 执行成功的回掉函数
// onFulfilled(this.PromiseResult)
resolvePromise(onFulfilled)
} else if(state==="rejected")
// onRejected(this.PromiseResult)
resolvePromise(onRejected)
} else if(state ==="pending") {
console.warn("遇到了异步函数,此时的状态肯定是pending,那么就把这个异步处理函数放到成功或者失败回调函数中,等到reject()或者resolve()的时候,再去调用");
// console.log(onFulfilled, onRejected);
this.onFulfilledCallbacks.push(resolvePromise.bind(this, onFulfilled))
this.onRejectedCallbacks.push(resolvePromise.bind(this, onRejected))
}
})
}
因为then方法是支持链式调用的,所以then方法的返回值也需要是一个MyPromise实例对象,所以我们在上面基础上做一定的修改
MyPromise.prototype.then = function(onFulfilled, onRejected) {
let state = this.PromiseState;
// 首先校验这两个参数是不是一个函数
onFulfilled = typeof onFulfilled === "function" ? onFulfilled : val => val
onRejected = typeof onRejected === "function" ? onRejected : reason => { throw reason }
var thenPromise = new MyPromise((resolve, reject) => {
const resolvePromise = cb => {
setTimeout(() => {
try {
const x = cb(this.PromiseResult)
if (x === thenPromise) {
// 不能返回自身哦
throw new Error('不能返回自身。。。')
}
if (x instanceof MyPromise) {
// 如果返回值是Promise
// 如果返回值是promise对象,返回值为成功,新promise就是成功
// 如果返回值是promise对象,返回值为失败,新promise就是失败
// 谁知道返回的promise是失败成功?只有then知道
x.then(resolve, reject)
} else {
// 非Promise就直接成功
resolve(x)
}
} catch (err) {
// 处理报错
reject(err)
throw new Error(err)
}
})
}
if(state === "fulfilled") {
// 执行成功的回掉函数
// onFulfilled(this.PromiseResult)
resolvePromise(onFulfilled)
} else if(state==="rejected"){
// onRejected(this.PromiseResult)
resolvePromise(onRejected)
} else if(state ==="pending") {
console.warn("遇到了异步函数,此时的状态肯定是pending,那么就把这个异步处理函数放到成功或者失败回调函数中,等到reject()或者resolve()的时候,再去调用");
// console.log(onFulfilled, onRejected);
this.onFulfilledCallbacks.push(resolvePromise.bind(this, onFulfilled))
this.onRejectedCallbacks.push(resolvePromise.bind(this, onRejected))
}
})
return thenPromise
}
MyPromise.resolve()
快速创建一个成功的MyPromise对象
MyPromise.__proto__.resolve = function(value) {
return new MyPromise((resolve, reject)=> {
resolve(value)
})
}
MyPromise.reject()
快速创建一个失败的MyPromsie对象
MyPromise.__proto__.reject = function(reason) {
return new MyPromise((resolve, reject)=> {
reject(reason)
})
}
MyPromise.all()
这个函数接受一个数组类型的参数,该数组的每一项都是一个Promise,或者非Promise的对象。
如果每一项的Promise的状态结果都是fulfilled,也就是成功的,那么这个函数的返回结果就是所有Promise的执行结果列表,状态为fulfilled,并且和传入数组顺序一致
如果有至少一个Promise的状态是rejected,那么这个函数的返回结束就是这个失败的Promise的结果,并且状态为rejected
MyPromise.__proto__.all = function(arr) {
if(!Array.isArray(arr)) throw new Error("必须传入一个属猪")
let resultArr = []
let count = 0;
return new MyPromise((resolve, reject)=>{
for(let i = 0;i< arr.length; i++) {
if(arr[i] instanceof MyPromise) {
arr[i].then(res=>{
// 这里不能使用push添加,顺序会错乱
resultArr[i] = res;
count++;
if(count === arr.length) return resolve(resultArr)
},err=>{
return reject(err)
})
} else {
resultArr[i] = arr[i]
}
}
})
}
MyPromise.race()
接收一个数组类型的参数,返回结果是最先执行完的一个Promise,无论这个Promise事是成功还是失败的Promise
MyPromise.__proto__.race = function(arr) {
if(!Array.isArray(arr)) throw new Error("传入参数必须是一个数组")
return new MyPromise((resolve, reject)=>{
arr.forEach((promise)=>{
if(promise instanceof MyPromise) {
promise.then(res=>{
return resolve(res)
}, err=>{
return reject(err)
})
} else {
return resolve(promise)
}
})
})
}
MyPromise.any()
该函数接受一个数组类型参数
1、如果参数中有一个Promise的状态是resolve,Promise.any() 返回一个resolve状态的Promise;
2、如果参数中全部的Promise的状态都变成了reject, Promise.any() 返回一个 reject 状态的Promise;3、如果传递了一个空的数组,那么返回一个reject状态的Promise
MyPromise.__proto__.any = function(arr) {
if(!Array.isArray(arr)) throw new Error("传入参数必须是一个数组")
let count = 0;
return new MyPromise((resolve, reject)=>{
arr.forEach((promise, index)=>{
if(promise instanceof MyPromise) {
promise.then(res=>{
resolve(res)
}, err=>{
count++;
if(count == arr.length) throw new Error("AggregateError: All MyPromises were rejected")
})
} else {
resolve(promise)
}
})
})
}
MyPromise.allSettled()
该函数接收一个数组类型的参数
返回所有Promise的处理结果 如果不是一个Promise,那么返回成功的Promise
value是成功的Promise返回结果 reason是失败的返回结果
[
{state: "rejected", reason: "***"},
{state: "fulfilled", value: "***"},
]
MyPromise.__proto__.allSettled = function(arr) {
if(!Array.isArray(arr)) throw new Error("传入参数必须是一个数组")
return new MyPromise((resolve, reject)=>{
let resultArr = []
// let count = 0;
for(let i = 0;i< arr.length;i++) {
if(arr[i] instanceof MyPromise) {
let obj = {status: "fulfilled"}
arr[i].then(res=>{
obj.value = res;
},err=>{
obj.status = "rejected"
obj.reason = err;
})
resultArr[i] = obj
} else {
resultArr[i] = {
status: "fulfilled",
value: arr[i]
}
}
}
resolve(resultArr)
})
}