promi实现原理解析(设计思想)

更新时间:2023-06-28 19:50:01 阅读: 评论:0

promi实现原理解析(设计思想)
promi作为es6的基本api,⼤家都⽤的很熟悉了。不过谈到promi的实现原理,可能很多⼈还很陌⽣,这⾥对promi的内部实现原理做下解析。
研究⼀种api或⼀个框架,最好的⽅法是要知道这背后能够实现的价值和⾃我提升,不能为了研究⽽研究。⽹上有很多博客或者专栏也在介绍,那么我们为什么要研究promi的内部实现原理呢,这对于编程或者业务⼜有怎样的帮助呢。
研究promi原理的必要性:
1,和回调函数的写法在更深层次有所对⽐
2,更加深⼊的认识异步事件操作
3,提升开发者⼈员的思维模式
⼀句话总结promi原理:resolve, reject两个函数控制promi内部状
态,promi.then()根据状态执⾏不同的逻辑,实现异步。
promi的简单实现:
⽹上有各种帖⼦来实现promi,但是介绍设计思路的很少,以⾄于很多⼈并不知道为什么要这样去实现,接下来会从设计上来介绍⼀种promi的简单实现。
设计思路:
1,封装⼀个构造函数myPromi,给其设定⼀个内部状态status,有三种取值,分别对应peomi的三种状态 ,设定⼀个内部对象data,⽤于存储promi对象当前的值
说明:使⽤promi时,是进⾏new⼀个实例
根据promi/A+规范,promi内部应该有三种状态
promi对象内部有⼀个全局的存储值,以便promi进⾏链式调⽤
function myPromi(){
const lf = this;
lf.status = 'pending';
lf.data = undefined;
}
英语教学工作总结
2,给构造函数myPromi添加两个⽅法 resolve, reject
说明:在new Promi时会传⼊接收两个⼊参 resolve, reject的回调函数,这两个函数需要在promi内部定义
function myPromi(cb){  //参数为⼀个函数,接收resolve, reject两个参数什么运动
const lf = this;
lf.status = 'pending';
lf.data = undefined;
function resolve(value){
if(lf.status == 'pending'){
lf.status = 'fulfilled'
lf.data = value;
大雁console.ResolvedCallback)
}
}
function reject(reason){
if(lf.status == 'pending'){
lf.status = 'failed'
lf.data = reason;
}
}
try  {
cb(resolve,reject)
} catch(e) {
reject(e)
}
}
3,给myPromi构造函数的原型上(实例上)添加⼀个then⽅法
说明:根据promi/A+规范,每⼀个promi实例都有⼀个then⽅法
myPromi.prototype.then = function(){
}
以上三个步骤⽐较好理解,相信都可以看懂
接下来就有点绕:
4,then函数接收两个参数,onFulfilled(onResolved),onRejected
说明:为什么要接收两个参数,
根据promi/a+规范,then⽅法最终都要返回⼀个promi,在then⽅法执⾏过程中,需要解析当前promi对象的状态,以及向下⼀个promi对象传值,如果是pending,不做解析,另外两种状态在设置后会去执⾏对应状态的队列函数,所以then要接收两个函数,以放到各⾃的队列函数中
myPromi.prototype.then = function(onResolve, onReject){
}
5,then⽅法处理fulfilled, failed状态
说明:then⽅法返回的是promi函数,如果promi.then(onFulfilled(onResolved),onRejected)调⽤then⽅法,这时的状态会是fulfilled或者failed,此时是promi.then(onFulfilled(onResolved),onRejected)返回的promi的调⽤then,这时针对不同的状态做不同的逻辑处理
6,调⽤then⽅法后,获取promi对象中的data是被then中的回调函数onFulfilled(onResolved),onRejected处理后的值说明:链式调⽤后⾯的then需要⽤到前⾯then⽅法回调函数处理的返回值
7,由于then⽅法需要在resolve后异步执⾏,所以要设置两个全局状态队列onResolvedCallback ,onRejectedCallback 8,在resolve(data)时,状态并没有⽴即改变,所以resolve函数内部要设置为异步调⽤,即使⽤tTimeout(), reject同理说明:针对7,8:
在创建promi对象时,设置resolve或者reject后会在异步队列中放⼊异步任务,更改状态,执⾏对应队列函数;
创建对象后,then同步调⽤,优先将onFulfilled(onResolved)或者onRejected放⼊队列中(这⾥先考虑同步调⽤)
五行是什么
myPromi.prototype.then = function(onResolved,onRejected){
console.log('我是promi的then')
const lf = this;
let promi2;
//判断是不是onResolved,onRejected函数
onResolved = typeof onResolved === 'function' ? onResolved : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : value => value;
//判断promi对象的当前状态
if(lf.status == 'fulfilled'){
console.log('异步调⽤promi或者多次调⽤,这⾥已经解析了')
promi2 = new myPromi(function(resolve,reject){
try{
let x = onResolved(lf.data)
//判断onResolved是否返回⼀个myMromi对象
if(x instanceof myPromi){
x.then(resolve,reject)
} el {
resolve(x)
}
}catch(e){
reject(e)
}
})
return promi2;
}
if(lf.status == 'failed'){
promi2 = new myPromi(function(resolve,reject){
try{
let x = onRejected(lf.data)
if(x instanceof myPromi){
x.then(resolve,reject)
} el {
resolve(x)
}
}catch(e){
reject(e)
}
})
}
//promi对象当前状态为pending,此时并不能确定调⽤onResolved还是onRejected,需要等当前Promi状态确定。
if(lf.status == 'pending'){
promi2 = new myPromi(function(resolve, reject){
//向数组添加函数并不会执⾏该函数,执⾏过push同步任务后,会执⾏异步任务tTimeout
try{
// ('我是promi的pending状态',lf.status)
// console.log('pending状态下的lf.data',lf.data)
let x = onResolved(lf.data)
if(x instanceof myPromi){
x.then(resolve,reject)
}el{
console.log('x不是 promi:',x)
resolve(x)
}
}catch(e){
reject(e)
}
})
try{
let x = onRejected(lf.data)
if(x instanceof myPromi){
x.then(resolve,reject)
}el{
resolve(x)
}
}catch(e){
reject(e)
}
})
})
return promi2
}
}
季子平安否
上⾯已经实现了⼀个简易的promi,可以进⾏简单的测试
测试简单使⽤:
const promi = new myPromi((resolve) => {
resolve(1); //resolve函数内部的执⾏是异步的会先去执⾏promi.then()这个同步函数});
女性饮食promi.then(data => {
cosnole.log(data)
})
测试多次调⽤:
//then⽅法的返回值是下次promi then中的值
const test = promi.then(data => {
console.log('返回⼀个promi对象',data)
return 'test'
});
test.then(data => {
console.log('我是⼆次返回promi data',data)
})
测试异步调⽤,异步调⽤的处理逻辑会加在 fulfilled和reject状态中
const promia = new myPromi((resolve) => {
resolve(100); //resolve函数内部的执⾏是异步的会先去执⾏promi.then()这个同步函数    });
tTimeout(function(){
promia.then(data => {
cosole.log(data)
})
},5000)
关于promi对像实例的⽅法这⾥不再探讨。
本⽂具体代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta chart="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
儿童简笔画小兔子<title>Promi⼿动实现</title>
</head>
<body>
</body>
<script>
//⼿动实现promi
function myPromi(cb){  //参数为⼀个函数,接收resolve, reject两个参数
const lf = this;
lf.status = 'pending';
lf.data = undefined;
护肤步骤
function resolve(value){
console.log('我是同步的resolve')
tTimeout(() => {  //这⾥异步执⾏,否则会直接执⾏掉
console.warn('开始执⾏异步resolve')
if(lf.status == 'pending'){
lf.status = 'fulfilled'
lf.data = value;
console.ResolvedCallback)
}
})
}
function reject(reason){
tTimeout(() => {
if(lf.status == 'pending'){
lf.status = 'failed'
lf.data = reason;
}
})
}
try  {
cb(resolve,reject)
} catch(e) {
reject(e)
}
}
//基本的then⽅法
// myPromi.prototype.then = function(onResolve, onReject){
//    ResolvedCallback.push(onResolve);
//    RejectedCallback.push(onReject)
// }
//由于then要返回Promi对象,所以对then⽅法进⾏如下改造
myPromi.prototype.then = function(onResolved,onRejected){
console.log('我是promi的then')
const lf = this;
let promi2;
//判断是不是onResolved,onRejected函数
onResolved = typeof onResolved === 'function' ? onResolved : value => value;

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

本文链接:https://www.wtabcd.cn/fanwen/fan/82/1061150.html

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

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