如何利用ES6进行Promi封装总结

更新时间:2023-06-28 19:54:35 阅读: 评论:0

如何利⽤ES6进⾏Promi封装总结
原⽣Promi解析
简介
promi是异步编程的⼀种解决⽅案,⽐传统的解决⽅案--回调函数和事件--更合理和强⼤。
promi简单说就是⼀个容器,⾥⾯保存着某个未来才会结束的事件(通常是⼀个异步操作)的结果,从语法上来说,Promi是⼀个对象,从它可以获取异步操作的消息,Promi提供统⼀的API,各种异步操作都可以⽤同样的⽅法进⾏处理
特点
对象的状态不受外界影响,Promi对象代表⼀个异步操作,有三种状态:Pendding、fulfilled、rejected。只有异步操作的结果,可以决定当前是哪⼀种状态,其他操作都⽆法改变这个状态。
⼀旦状态改变,就不会在变,任何时候都可以得到这个结果,只有两种可能:从Pendding变为fulfilled和从Pendding变为rejected。只要这两种情况发⽣,状态就凝固了,会⼀直保持这个结果,这时就称为resolved。
利⽤es6进⾏Promi封装
处理同步任务
原⽣⽅法调⽤⽅式
new Promi((resolve,reject)=>{
resolve(1)
}).then(res=>{
console.log(res) //1
})
同步封装思考
1.由调⽤⽅式可见Promi是⼀个类
2.它接收⼀个回调函数,这个回调函数接受resolve和reject⽅法作为参数
3.当状态改变后执⾏then⽅法,并将resolve或reject的结果作为then⽅法接受回调函数的参数
class Mypromi{
constructor(callback){
this.status='pendding'
//成功结果
this.s_res = null
// 失败结果
this.f_res = null
callback((arg)=>{ // 使⽤箭头函数this不会丢失
// 改变状态为成功
this.status = 'fulfilled'
this.s_res = arg
},(arg)=>{
// 改变状态为失败
this.status = 'rejected'
this.f_res = arg
})
}
then(onresolve,onreject){
if(this.status === 'fulfilled'){ // 当状态为成功时
onresolve(this.s_res)
}el if(this.status === 'rejected'){ // 当状态为失败时
男的成语
onreject(this.f_res)
}
}
}
处理异步任务
原⽣调⽤⽅式
new Promi((resolve,reject)=>{
tTimeOut(()=>{
resolve(1)
},1000)
}).then(res=>{
console.log(res)
})
异步封装思考
1.根据js执⾏机制,tTimeOut属于宏任务,then回调函数属于微任务,当主线程执⾏完成后,会从异步队列中取出本次的微任务先执⾏。
2.也就是说,then⽅法执⾏时,状态还没有改变,所有我们需要将then⽅法执⾏的回调保存起来,等到异步代码执⾏完成后,在统⼀执⾏then⽅法的回调函数
class Mypromi{
constructor(callback){
this.status='pendding'
//成功结果
this.s_res = null
麦仁粥的做法大全
// 失败结果
this.f_res = null
this.query = [] // ++
callback((arg)=>{ // 使⽤箭头函数this不会丢失
// 改变状态为成功
this.status = 'fulfilled'
this.s_res = arg
// 当状态改变后,统⼀执⾏then⽅法的回调
this.query.forEach(item=>{
})
},(arg)=>{
// 改变状态为失败
this.status = 'rejected'
this.f_res = arg
// 当状态改变后,统⼀执⾏then⽅法的回调
this.query.forEach(item=>{
})
})
}
then(onresolve,onreject){
if(this.status === 'fulfilled'){ // 当状态为成功时
onresolve(this.s_res)
}el if(this.status === 'rejected'){ // 当状态为失败时
onreject(this.f_res)
}el{ // ++ 状态没有改变
this.query.push({ // 保存回调函数到队列中
resolve:onresolve,
reject:onreject
})
}
}
}
处理链式调⽤
原⽣调⽤⽅式
new Promi((resolve,reject)=>{
resolve(1)
}).then(res=>{
return res
}).then(res=>{
console.log(res)
})
链式调⽤思考
原⽣的Promi对象的then⽅法,返回的也是⼀个Promi对象,⼀个新的Promi才能⽀持链式调⽤
下⼀个then⽅法可以接受上⼀个then⽅法的返回值作为回调函数的参数
主要考虑上⼀个then⽅法的返回值:
1.Promi对象/具有then⽅法的对象
2.其他值
第⼀个then⽅法返回⼀个Promi对象,它的回调函数接受resFn和rejFN两个回调函数作为参数,把成功状态的处理封装为handle函数,接受成功的结果作为参数
在handle函数,根据onresolve返回值的不同做出不同的处理
class Mypromi{
constructor(callback){
this.status='pendding'
//成功结果
this.s_res = null
// 失败结果
this.f_res = null
this.query = [] // ++
callback((arg)=>{ // 使⽤箭头函数this不会丢失
// 改变状态为成功
this.status = 'fulfilled'
this.s_res = arg
// 当状态改变后,统⼀执⾏then⽅法的回调
this.query.forEach(item=>{
})
},(arg)=>{
// 改变状态为失败
this.status = 'rejected'
this.f_res = arg
// 当状态改变后,统⼀执⾏then⽅法的回调
this.query.forEach(item=>{
})
})
}
then(onresolve,onreject){
return new Mypromi((resFN,rejFN)=>{
if(this.status === 'fulfilled'){ // 当状态为成功时
handle(this.s_res)
}el if(this.status === 'rejected'){ // 当状态为失败时
errBack(this.f_res)
}el{ // ++ 状态没有改变
this.query.push({ // 保存回调函数到队列中
resolve:onresolve,
棒子面粥的做法reject:onreject
})
}
function handle(value){
// 当then⽅法的onresolve⽅法有返回值时,保存其返回值,没有使⽤其保存的值
let returnVal = onresolve instanceof Function && onresolve(value) || value
// 如果onresolve⽅法返回的是promi对象,则调⽤其then⽅法
if(returnVal&&returnVal['then'] instanceof Function){
returnVal.then(res=>{
resFN(res)
},err=>{
rejFN(err)
})
}el{
resFN(returnVal)
}
}
function errBack(reason){
if(onreject instanceof Function){
let returnVal = reject(reason)
if(typeof returnVal !== 'undenfined' && returnVal['then'] instanceof Function){
returnVal.then(res=>{
resFN(res)
},err=>{
rejFN(err)
})
}el{
resFN(returnVal)
}
}el{
rejFN(reason)
}
}
})
Promi.all和Promi.race⽅法
原⽣调⽤⽅式
Promi.all⽅法接受⼀个数组,数组中的每⼀项都是⼀个Promi实例,只有数组中的所有Promi实例的状态都变为fulfilled 时,此时整个状态才会变成fulfilled,此时数组中所有Promi实例的返回值组成⼀个新的数组,进⾏传递。
Promi.race⽅法和Promi.all⽅法⼀样,如果不是Promi实例,就会先调⽤solve⽅法,将参数转为Promi实例,在进⾏下⼀步处理。
只要数组中有⼀个参数的状态变为fulfilled就会进⾏传递
// 将现有对象转换为Promi对象
if(typeof arg == 'undefined' || arg==null){ // 不带有任何参数
return new Mypromi(resolve=>{
resolve(arg)
})
}el if(arg instanceof Mypromi){ // 是⼀个Mypromi实例
return arg
}el if(arg['then'] instanceof Function){ // 具有then⽅法的对象
return new Mypromi((resolve,reject)=>{
arg.then(res=>{
resolve(res)
},err=>{
reject(err)
})
})
}el{ // 参数不是具有then⽅法的对象,或根本不是对象
return new Mypromi(resolve=>{
resolve(arg)
})
}
}
Mypromi.all = (arr)=>{
if(!Array.isArray(arr)){
throw new TypeError('参数必须是⼀个数组')
}
return new Mypromi((resolve,reject)=>{
let i=0,result=[]
单词分类next()
functon next(){
// 如果不是Mypromi实例需要转换补血最快的食物
result.push(res)
i++
if(i===arr.length){
resolve(result)
}el{
next()
}
},reject)
}
})
}
Mypromi.race = (arr)=>{
if(!Array.isArray(arr)){
throw new TypeError('参数必须是⼀个数组')
}
return new Mypromi((resolve,reject)=>{
let done = fal
arr.forEach(item=>{
if(!done){
resolve(res)
done = true
}
},err=>{
if(!done){
reject(res)
绵山done = true
}
cad填充命令
})
}
腌萝卜怎么做
处理Mypromi状态确定不能改变的特性
在重写callback中的resolve和reject⽅法执⾏前,先判断状态是否为'pendding'以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

本文发布于:2023-06-28 19:54:35,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1059125.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:状态   函数   回调   改变   结果
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图