手写实现Promise,助你透彻理解Promise
//声明一个构造类
class PromiseSelf{
//记录当前任务状态
static PENDING="pending"
static FULFILLED='fulfilled'
static REJECTED='rejected'
//new的时候要传递一个函数包含两个参数分别用于调用成功和失败回调
constructor(executor){
//对象产生以后赋默认值
this.value=null;
this.status=PromiseSelf.PENDING;
//用于处理主线程产生宏任务以后 解决宏任务执行回调
this.callbacks=[];
//解决运行异常抛出机制
try {
//构造是便会执行传过来的函数 CLASS默认为严格模式 我们在调用时会发现
//函数中this指向为undefined 因为我们是直接调用 本身应该指向window
//使用严格模式禁止提升 变成了undefined 这时需要我们手动绑定this
executor(this.resolve.bind(this),this.reject.bind(this))
} catch (error) {
//当运行出现异常调用失败函数
this.reject(error);
}
}
resolve(value){
//根据Promise运行机制可以得知 当状态已经改变时
//将不会再次改变状态 所以当已经调用过改变状态的函数时
//让其他改变状态的函数失效
//if用来过滤已经更改过状态的操作
if(this.status==PromiseSelf.PENDING){
this.value=value;
this.status=PromiseSelf.FULFILLED;
//当new Promise时没有执行改变状态的操作 callbacks才会有值 then函数会将回调函数存入callbacks数组中
//等待状态改变后 来执行回调
setTimeout(() => {
//如果promise执行时遇到了 改变当前promise状态的宏任务 这个回调必须晚于其执行体内同步操作
//类似如下情景 必须先输出1 然后执行输出回调的内容
// setTimeout(()=>{
// resolve();
// console.log("1");
// },0)
this.callbacks.map(callback=>{
callback.onFULFILLED(value)
}, 0);
})
}
}
reject(value){
if(this.status==PromiseSelf.PENDING){
this.value=value;
this.status=PromiseSelf.REJECTED;
setTimeout(() => {
this.callbacks.map(callback=>{
callback.onREJECTED(value)
}, 0);
})
}
}
//想要实现链式调用 then返回的一定是一个新的promise
then(onFULFILLED,onREJECTED){
//如果传过来的不是函数 我们给他转换成一个函数
if(typeof onFULFILLED != 'function'){
//因为then在没有处理的时候会有穿透效果
//这个时候我们要将数据传出去
onFULFILLED=(value)=>{ return value}
}
if(typeof onREJECTED != 'function'){
onFULFILLED=(value)=>{ return value}
}
//返回一个promise 使其能链式调用
return new PromiseSelf((resolve,reject)=>{
//注意这里是箭头函数 this指向的是外面的对象
//而我们构造传过来的(resolve,reject)是已经使用bind强制绑定过this的
//所以这两个方法指向的才是我们正在构造的promise
if (this.status==PromiseSelf.PENDING) {
this.callbacks.push({
onFULFILLED:value=>{
try {
//保存之前返回的数据 在调用我们新构造的promise的改变状态的方法
let result = onFULFILLED(value);
//判断返回的是普通数据还是一个promise进行分别处理
if(result instanceof PromiseSelf){
result.then(res=>{
//用上一个promise返回的promise的状态来改变我们当前new的promise的状态
//我说的可能有点绕口
resolve(res)
},err=>{
reject(err)
})
}else{
resolve(result)
}
} catch (error) {
reject(error)
}
},
onREJECTED:(value)=>{
try {
let result=onREJECTED(value)
if(result instanceof PromiseSelf){
result.then(res=>{
resolve(res)
},err=>{
reject(err)
})
}else{
resolve(result)
}
} catch (error) {
reject(error)
}
}
});
}
if(this.status==PromiseSelf.FULFILLED){
setTimeout(() => {
try {
let result= onFULFILLED(this.value);
if(result instanceof PromiseSelf){
result.then(res=>{
resolve(res)
},err=>{
reject(err)
})
}else{
resolve(result)
}
} catch (error) {
reject(error)
}
}, 0);
}
if(this.status==PromiseSelf.REJECTED){
setTimeout(() => {
try {
let result= onREJECTED(this.value);
if(result instanceof PromiseSelf){
result.then(res=>{
resolve(res)
},err=>{
reject(err)
})
}else{
resolve(result)
}
} catch (error) {
reject(error)
}
}, 0);
}
})
}
}
//注意使用then的时候成功回调和错误回调都必须写上 可以只是个空函数 但必须有
//不足之处还望谅解 后续改进
let bb=new PromiseSelf((resolve,reject)=>{
resolve("as")
}).then(res=>{
console.log(res);
return new PromiseSelf(res=>{
res("assdasdasd")
})
},err=>{}).then(res=>{
console.log(res);
},err=>{})
console.log(bb);

浙公网安备 33010602011771号