当前位置:网站首页>ES5和SE6来实现一个Promise效果
ES5和SE6来实现一个Promise效果
2022-08-10 13:07:00 【快乐的蜜蜂】
这个是ES5的写法
function myPromise(executor) {
// 定义promise的状态
let self = this;
self.status = "pendding";
self.value = null; // 成功之后 返回数据
self.reason = null; // 失败之后返回原因
// 这个是 发布订阅
self.fulfilledCallbackList = [];
self.rejectCallbackList = [];
// 定义完成时的方法
function resolve(value) {
if (self.status == "pendding") {
self.status = "fulfilled";
self.value = value;
self.fulfilledCallbackList.forEach(item => item(value));
}
}
// 这个是 异常时候的方法
function reject(err) {
if (self.status == "pendding") {
self.status = "rejected";
self.reason = err;
self.rejectCallbackList.forEach(item => item(err));
}
}
// 这个是 立即执行 executor里面的方法
try {
executor && executor(resolve, reject);
} catch (err) {
reject(err.message);
}
}
// 这个是 原型链上面的 then 方法
myPromise.prototype.then = function (onFulfilled, onRejected) {
// 这里 还要 判断一下 传入进来 是不是一个方法
onFulfilled = typeof onFulfilled == 'function' ? onFulfilled : function (data) { resolve(data) };
onRejected = typeof onRejected == 'function' ? onRejected : function (err) { throw err; }
let self = this;
// 这里是 then 里面的回调部分
if (self.status == "fulfilled") {
// 链式调用 就是 直接返回一个 Promise
return new myPromise((resolve, reject) => {
try {
let x = onFulfilled(self.value);
x instanceof myPromise ? x.then(resolve, reject) : resolve(x);
} catch (err) {
reject(err);
}
});
}
// 这个是 失败的状态
if (self.status == "rejected") {
return new myPromise((resolve, reject) => {
try {
let x = onRejected(self.reason);
x instanceof myPromise ? x.then(resolve, reject) : resolve(x);
} catch (err) {
reject(err);
}
});
}
// 这个是 pendding的状态
if (self.status == "pendding") {
return new myPromise((resolve, reject) => {
self.fulfilledCallbackList.push(() => {
let x = onFulfilled(self.value);
x instanceof myPromise ? x.then(resolve, reject) : resolve(x);
});
self.rejectCallbackList.push(() => {
let x = onRejected(self.reason);
x instanceof myPromise ? x.then(resolve, reject) : resolve(x);
});
});
}
}
myPromise.prototype.catch = function(fn) {
this.then(null, fn);
}
const aaa = new myPromise((resolve, reject) => {
console.log(111);
setTimeout(() => {
resolve("2222222222222");
}, 2000);
}).then((res, rej) => {
return new myPromise((re1, rj1)=>{
re1(res + "sdfsdfsdfsdf");
});
}).then((res1, rej1)=>{
console.log(res1);
});
console.log("aaa", aaa);
这个是ES6 Class版本的实现
class MyPromise {
constructor(executor) {
// 这个是 promise的状态机制
this.status = "pendding";
// 这个是 成功的值
this.value = null;
// 这个是 失败的值
this.reason = null;
// 这里是 发布订阅的部分
this.fulfilledCallbacks = [];
this.rejectedCallbacks = [];
// 这个是 立即执行 executor里面的方法
try {
// 这里要绑定 this , 然后下面的 函数 才能 拿到这里的this
executor && executor(this.resolve.bind(this), this.reject.bind(this));
} catch (err) {
this.reject(err.message);
}
}
resolve(data) {
if (this.status == "pendding") {
this.status = "fulfilled";
this.value = data;
// 这个是 发布 订阅里面的函数
this.fulfilledCallbacks.forEach(item => item(data));
}
}
// 这个是 reject 拒绝的方法
reject(err) {
if (this.status == "pendding") {
this.status = "rejected";
this.reason = err;
this.rejectedCallbacks.forEach(item => item(err));
}
}
// 这个是 then 方法
then(onFulfilled, onRejected) {
let self = this;
// 这个是 判断 传进来的是否是 方法
onFulfilled = typeof onFulfilled == 'function' ? onFulfilled : function (data) { self.resolve(data) };
onRejected = typeof onRejected == 'function' ? onRejected : function (err) { throw err };
// 这里是成功的值
if (self.status == "fulfilled") {
// 这里是 链式调用的部分 通过返回 MyPromise 来实现
return new MyPromise((resolve, reject) => {
try {
let x = self.onFulfilled(self.value);
x instanceof MyPromise ? x.then(resolve, reject) : self.resolve(x);
} catch (error) {
reject(error);
}
});
}
// 这里是 失败的时候
if (self.status == "rejected") {
return new MyPromise((resolve, reject) => {
try {
let x = onRejected(self.reason);
x instanceof MyPromise ? x.then(resolve, reject) : self.resolve(x);
} catch (error) {
reject(error);
}
});
}
// 这里是 pendding 加载的时候
if (self.status == "pendding") {
return new MyPromise((resolve, reject) => {
self.fulfilledCallbacks.push(() => {
let x = onFulfilled(self.value);
x instanceof MyPromise ? x.then(resolve, reject) : self.resolve(x);
});
self.rejectedCallbacks.push(() => {
let x = onRejected(self.reason);
x instanceof MyPromise ? x.then(resolve, reject) : self.resolve(x);
});
});
}
}
catch(fn) {
this.then(null, fn);
}
}
const aaa = new MyPromise((resolve, reject) => {
console.log(111);
setTimeout(() => {
resolve("我是输出.");
}, 2000);
}).then((res, rej) => {
return new MyPromise((re1, rj1)=>{
console.log("res", res);
setTimeout(() => {
re1(res + "对,我是后面的输出");
}, 2000);
});
}).then((res1, rej1)=>{
console.log(res1);
});
console.log("aaa", aaa);
边栏推荐
- 【mysql索引实现原理】
- Reversing words in a string in LeetCode
- the height of the landscape
- 数据产品经理那点事儿 一
- 一种能让大型数据聚类快2000倍的方法,真不戳
- Borg Maze (bfs+最小生成树)
- C#中导入其它自定义的命名空间
- ArcMAP has a problem of -15 and cannot be accessed [Provide your license server administrator with the following information:Err-15]
- 【百度统计】用户行为分析
- 【量化交易行情不够快?】一文搞定通过Win10 wsl2 +Ubuntu+redis+pickle实现股票行情极速读写
猜你喜欢
11 + chrome advanced debugging skills, learn to direct efficiency increases by 666%
表中存在多个索引问题? - 聚集索引,回表,覆盖索引
R语言实战应用案例:论文篇(一)-特殊柱形图绘制
【黑马早报】雷军称低谷期曾想转行开酒吧;拜登正式签署芯片法案;软银二季度巨亏230亿美元;北京市消协约谈每日优鲜...
Keithley DMM7510 accurate measurement of ultra-low power consumption equipment all kinds of operation mode power consumption
跨域的五种解决方案
Redis上云迁移实践
接口自动化测试基础篇
3DS MAX 批量导出文件脚本 MAXScript 带界面
bgp dual plane experiment routing strategy to control traffic
随机推荐
Pod生命周期
作业8.9 构建TCP协议的服务器
Prada, big show?In the yuan in the universe that!
malloc 函数详解
Code Casual Recording Notes_Dynamic Programming_70 Climbing Stairs
YTU 2295: KMP模式匹配 一(串)
CodeForces - 811A
Borg Maze (bfs+最小生成树)
BEVDet4D: Exploit Temporal Cues in Multi-camera 3D Object Detection 论文笔记
MySQL面试题整理
神经网络可视化有3D版本了,美到沦陷!(已开源)
[Advanced Digital IC Verification] Difference and focus analysis between SoC system verification and IP module verification
Inventory of Loudi Agricultural Products Inspection Laboratory Construction Guidelines
【POI 2008, BLO】割点
ABAP file operations involved in the Chinese character set of problems and solutions for trying to read
一种能让大型数据聚类快2000倍的方法,真不戳
Requirements for the construction of Loudi stem cell preparation laboratory
rpn:def concat_box_prediction_layers
C# InitializeComponent() does not exist in the current context
LeetCode·297.二叉树的序列化与反序列化·DFS·BFS