Js手写Promise
前言
作为一名合格的前端写手,手写一些常见的方法是不可或缺的一项技能。
手写Promise 涉及到高阶函数,在案例中我也会讲到,从一个小白的视角告诉各位职友
一、Promise是什么?
promie主要用于解决异步问题的,我们可以把它想象成一个鉴定机构,我把一件宝贝给到promise,promise返回一个结果,那这个结果肯定只有两种结果,真亦或假,不可能有半真半假的古董吧🙀。
古董的鉴定流程是 鉴定中=>鉴定结果=>(是真是假)真假的结果是不会改变的。
同样的,peomise 也有流程。pending=>fulfilled(成功)=>rejected(失败)也就是说 有两种可能,1、从pending到rejected
2、从pending到fulfilled
且状态变了就不会再改变。
二、使用
代码如下(示例):
// resolve 就相当于上方的fulfilled成功状态(使其变为成功状态)
new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('Hello,我是Hy')
},1000)
})
2.Promise的原型上有then方法,接受两个参数,这两个参数也是函数,第一个函数是针对于成功的执行,第二个是针对于失败的执行。
代码如下(resolve示例):
new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('Hello,我是Hy')
},1000)
}).then((res)=>{
console.log(res);//res这个参数就是resolve 调用后传的data,既Hello,我是Hy
},(req)=>{
console.log(req);
})
// 一秒钟后打印 Hello,我是Hy
代码如下(reject示例):
new Promise((resolve,reject)=>{
setTimeout(()=>{
reject('Hello,我是Hy')
},1000)
}).then((res)=>{
console.log(res);
},(req)=>{
console.log(req);//req这个参数就是reject调用后传的data,既Heelo,我是Hy
}).catch((err)=>{
console.log(err);
//catch 也可以接受错误参数,比如then里面的第一个参数出现错误 总不能一直then、then吧。catch 就是那个个兜底的
})
// 一秒钟后打印 Heelo,我是Hy
正题 手写Promise(只为简单)
//首先定义一个类 为什么要用类,其他的不行? 可以,但是不觉得 原生promise 是 new出来的吗?
class MyPeomise{
//callback 是一个函数不要过多研究,跟着我走,这个函数里面接受两个参数,上方有讲(一个是resolve,一个是reject)
constructor(callback){
this.res = null; //定义两个变量 接受函数传过来的值 相对于我上方传的 hello,我是Hy
this.req = null;
this.states = "pending"; //定义状态
try{ //开始执行
//首先这个函数接受两个参数
callback((res)=>{
this.states = "fulfilled" //第一个就是resolve 他把状态变为成功 也就是pending=>fulfilled
this.res = res;
},(req)=>{
this.states = "rejected" //第二个就是reject 他把状态变为成功 也就是pending=>rejected
this.req = req;
})
}catch(err){
console.log(err);
}
}
then(resolve,reject){ // then 里面包含两个函数 那我们就把第一个函数定义为resolve 第二个对应reject的函数名
if(this.states==='fulfilled'){ // 判断 如果是什么状态 把 我们的data(Hello,我是Hy)交给函数
// 交出去之后不要考虑 我们不要再去考虑这个函数做了什么
resolve(this.res)
}else if(this.states==='rejected'){
reject(this.req)
}
}
}
// 实现 输出Hello,我是Hy
new MyPeomise((resolve,reject)=>{
resolve('Hello,我是Hy')
}).then((res)=>{
console.log(res);
},(req)=>{
console.log(req);
})
promise异步实现
promise是解决异步的。但我们的手写的是同步代码 那我么怎么去实现异步呢?
//首先定义一个类 为什么要用类,其他的不行? 可以,但是不觉得 原生promise 是 new出来的吗?
class MyPeomise{
//callback 是一个函数不要过多研究,跟着我走,这个函数里面接受两个参数,上方有讲(一个是resolve,一个是reject)
constructor(callback){
this.res = null; //定义两个变量 接受函数传过来的值 相对于我上方传的 hello,我是Hy
this.req = null;
this.states = "pending"; //定义状态
// 存放成功的回调
this.onResolvedCallbacks = [];
// 存放失败的回调
this.onRejectedCallbacks= [];
try{ //开始执行
//首先这个函数接受两个参数
callback((res)=>{
this.states = "fulfilled" //第一个就是resolve 他把状态变为成功 也就是pending=>fulfilled
this.res = res;
// 依次将对应成功的函数执行
this.onResolvedCallbacks.forEach(fn=>fn());
},(req)=>{
this.states = "rejected" //第二个就是reject 他把状态变为成功 也就是pending=>rejected
this.req = req;
// 依次将对应失败的函数执行
this.onRejectedCallbacks.forEach(fn=>fn());
})
}catch(err){
console.log(err);
}
}
then(resolve,reject){ // then 里面包含两个函数 那我们就把第一个函数定义为resolve 第二个对应reject的函数名
if(this.states==='fulfilled'){ // 判断 如果是什么状态 把 我们的data(Hello,我是Hy)交给函数
// 交出去之后不要考虑 我们不要再去考虑这个函数做了什么
resolve(this.res)
}else if(this.states==='rejected'){
reject(this.req)
}else if(this.states==='pending'){
this.onResolvedCallbacks.push(() => { //由于还是pending状态 我们先把他放在数组 为什么准备两个数组呢?因为每个数组存放的函数不一样 一个是成功的回调函数
resolve(this.res)
});
this.onRejectedCallbacks.push(()=> {
reject(this.req);
})
}
}
}
// 实现 输出Hello,我是Hy
new MyPeomise((resolve,reject)=>{
setTimeout(()=>{
resolve('Hello,我是Hy')
},2000)
}).then((res)=>{
console.log(res);
},(req)=>{
console.log(req);
})
//记得点赞啊
总结
例如:以上就是今天要讲的内容,本文仅仅简单介绍了promis的使用,以及比较简单的手写promise,感谢支持,有不对的地方恳请评论区批评。