手写 promise
简易版实现基础功能
resolve,reject,then
class MyPromise {
constructor(executor) {
// 接收一个作为函数类型的参数,并执行
executor(this.resolve, this.reject);
}
// 结果值
PromiseResult;
// 默认状态
PromiseState = "pending";
// resolve 方法,用于将 Promise 状态设置为 fulfilled
// 如果PromiseState不是默认值那么直接返回,避免多次赋值
// 设置 Promise 结果值为传入的 value
resolve = (value) => {
if (this.PromiseState !== "pending") return;
this.PromiseState = "fulfilled";
this.PromiseResult = value;
};
// reject 方法,用于将 Promise 状态设置为 rejected
reject = (value) => {
if (this.PromiseState !== "pending") return;
this.PromiseState = "rejected";
this.PromiseResult = value;
};
// then 方法,Promise的回调函数
// 根据PromiseResult的值来判断执行哪一个回调函数
then = (onFulfilled, onRejected) => {
if (this.PromiseState === "fulfilled") {
onFulfilled(this.PromiseResult);
} else if (this.PromiseState === "rejected") {
onRejected(this.PromiseResult);
}
};
}
支持异步
then 调用时假如 promise 状态还是 pending 时,将两个回调函数存起来,当异步执行完,改变了状态,循环执行成功回调函数列表中的函数
class MyPromise {
constructor(executor) {
executor(this.resolve, this.reject);
}
// 成功回调函数
FulfilledCallback = [];
// 失败回调函数
RejecteddCallback = [];
PromiseState = "pending";
PromiseResult;
// 当异步执行完,改变了状态,循环执行成功回调函数列表中的函数,并将结果值传递
resolve = (value) => {
if (this.PromiseState !== "pending") return;
this.PromiseState = "fulfilled";
this.PromiseResult = value;
while (this.FulfilledCallback.length) {
this.FulfilledCallback.shift()(this.value);
}
};
reject = (value) => {
if (this.PromiseState !== "pending") return;
this.PromiseState = "rejected";
this.PromiseResult = value;
while (this.RejecteddCallback.length) {
this.RejecteddCallback.shift()(this.value);
}
};
then = (onFulfilled, onRejected) => {
if (this.PromiseState === "fulfilled") {
onFulfilled(this.PromiseResult);
} else if (this.PromiseState === "rejected") {
onRejected(this.PromiseResult);
} else if (this.PromiseState === "pending") {
// then调用时,状态为pending 则将函数函数存起来
this.FulfilledCallback.push(onFulfilled);
this.RejecteddCallback.push(onRejected);
}
};
}
链式调用
链式调用需要then()的返回值是Promise
class MyPromise {
// 其余代码
then = (onFulfilled, onRejected) => {
// 返回一个Promise对象
return new MyPromise((resolve, reject) => {
// resolvePromise 在pending阶段调用,传进去回调函数
// 在resolvePromise中执行回调函数,得到promiseObj
// 判断得到promiseObj类型是否是promise
// 如果是则通过promiseObj.then(resolve, reject)来改变then返回值MyPromise的状态
// 如果不是则默认成功,直接调用then返回值MyPromise的resolve方法
const resolvePromise = (callback) => {
const promiseObj = callback(this.PromiseResult);
if (promiseObj instanceof MyPromise) {
// 简写 相当于 promiseObj.then(value=>resolve(value),value=>reject(value))
promiseObj.then(resolve, reject);
} else {
resolve(promiseObj);
}
};
if (this.PromiseState === "fulfilled") {
resolvePromise(onFulfilled);
} else if (this.PromiseState === "rejected") {
resolvePromise(onRejected);
} else if (this.PromiseState === "pending") {
// 封装一下onFulfilled,onRejected回调函数,修改返回值promise的状态
this.FulfilledCallback.push(resolvePromise.bind(this, onFulfilled));
this.RejecteddCallback.push(resolvePromise.bind(this, onRejected));
}
});
};
}
all方法
接受一个promise数组,非promise的当做成功 全部成功返回结果数组,有一个失败则返回失败结果
static all = (promises) => {
return new MyPromise((resolve, reject) => {
let result = [];
let resultAdd = (res) => {
result.push(res);
if (result.length === promises.length) resolve(result);
};
promises.forEach((promise) => {
if (promise instanceof MyPromise) {
promise.then(res=>resultAdd(res),err=>reject(err));
} else {
resultAdd(promise);
}
});
});
};
any方法
接受一个promise数组 返回第一个成功结果,全部失败则报错
static any = (promises) => {0
return new MyPromise((resolve, reject) => {
promises.forEach((promise, index) => {
promise.then(
(value) => resolve(value),
(err) => {
if(index == promises.length-1) reject(new AggregateError("All promises were rejected"));
}
);
});
});
};
race方法 接受一个promise数组,非promise的当做成功 返回最快得到的结果,不论成功或者失败
static race = (promises) => {
return new MyPromise((resolve, reject) => {
promises.forEach((promise) => {
if(promise instanceof MyPromise){
promise.then(res=>resolve(res),err=>reject(err))
}else{
resolve(promise)
}
});
});
};
allSettled方法 接受一个promise数组,非promise的当做成功 把promise结果以数组方式返回
static allSettled = (promises) => {
return new MyPromise((resolve, reject) => {
let result = [];
let resultAdd = (status,res) => {
result.push({status,res});
if (result.length === promises.length) resolve(result);
};
promises.forEach((promise) => {
if (promise instanceof MyPromise) {
promise.then(res=>resultAdd('fulfilled',res),err=>resultAdd('rejected',err));
} else {
resultAdd('fulfilled',promise);
}
});
});
};
Promise.resolve()
static resolve = (value) => {
return new MyPromise((resolve) => resolve(value));
};
Promise.reject()
static reject = (value) => {
return new MyPromise((resolve,reject) => reject(value));
};
catch方法 接受一个回调函数 其实就是then方法第二参数,语法糖
catch = (callback)=>{
return this.then(undefined,callback)
}
finally方法 接受一个回调函数 无论结果是成功或者失败都会执行finally无法获取上一个promise传出来的值.then(() => value这个的话是为了finally后面调用then的话可以获取之前的finally获取的value
finally = (callback)=>{
return this.then(
(value) => MyPromise.resolve(callback()).then(() => value),
(reason) =>
MyPromise.resolve(callback()).then(() => {
throw reason;
})
);
}
完整代码
class MyPromise {
constructor(executor) {
executor(this.resolve, this.reject);
}
FulfilledCallback = [];
RejecteddCallback = [];
PromiseState = "pending";
PromiseResult;
resolve = (value) => {
if (this.PromiseState !== "pending") return;
this.PromiseState = "fulfilled";
this.PromiseResult = value;
while (this.FulfilledCallback.length) {
this.FulfilledCallback.shift()(value);
}
};
reject = (value) => {
if (this.PromiseState !== "pending") return;
this.PromiseState = "rejected";
this.PromiseResult = value;
while (this.RejecteddCallback.length) {
this.RejecteddCallback.shift()(value);
}
};
then = (onFulfilled, onRejected) => {
// 判断毁掉函数是否为空
onFulfilled =
typeof onFulfilled === "function" ? onFulfilled : (val) => val;
onRejected =
typeof onRejected === "function"
? onRejected
: (reason) => {
throw reason;
};
return new MyPromise((resolve, reject) => {
const resolvePromise = (callback) => {
queueMicrotask(() => {
const promiseObj = callback(this.PromiseResult);
if (promiseObj instanceof MyPromise) {
promiseObj.then(resolve, reject);
} else {
resolve(promiseObj);
}
});
};
if (this.PromiseState === "fulfilled") {
resolvePromise(onFulfilled);
} else if (this.PromiseState === "rejected") {
resolvePromise(onRejected);
} else if (this.PromiseState === "pending") {
this.FulfilledCallback.push(resolvePromise.bind(this, onFulfilled));
this.RejecteddCallback.push(resolvePromise.bind(this, onRejected));
}
});
};
catch = (callback) => {
return this.then(undefined, callback);
};
finally = (callback) => {
return this.then(
(value) => MyPromise.resolve(callback()).then(() => value),
(reason) =>
MyPromise.resolve(callback()).then(() => {
throw reason;
})
);
};
static all = (promises) => {
return new MyPromise((resolve, reject) => {
let result = [];
let resultAdd = (res) => {
result.push(res);
if (result.length === promises.length) resolve(result);
};
promises.forEach((promise) => {
if (promise instanceof MyPromise) {
promise.then(
(res) => resultAdd(res),
(err) => reject(err)
);
} else {
resultAdd(promise);
}
});
});
};
static any = (promises) => {
return new MyPromise((resolve, reject) => {
promises.forEach((promise, index) => {
promise.then(
(value) => resolve(value),
(err) => {
if (index == promises.length - 1)
reject(new AggregateError("All promises were rejected"));
}
);
});
});
};
static race = (promises) => {
return new MyPromise((resolve, reject) => {
promises.forEach((promise) => {
if (promise instanceof MyPromise) {
promise.then(
(res) => resolve(res),
(err) => reject(err)
);
} else {
resolve(promise);
}
});
});
};
static allSettled = (promises) => {
return new MyPromise((resolve, reject) => {
let result = [];
let resultAdd = (status, res) => {
result.push({ status, res });
if (result.length === promises.length) resolve(result);
};
promises.forEach((promise) => {
if (promise instanceof MyPromise) {
promise.then(
(res) => resultAdd("fulfilled", res),
(err) => resultAdd("rejected", err)
);
} else {
resultAdd("fulfilled", promise);
}
});
});
};
static resolve = (value) => {
return new MyPromise((resolve,reject) => resolve(value));
};
static reject = (value) => {
return new MyPromise((resolve,reject) => reject(value));
};
}