当前位置:网站首页>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);
边栏推荐
- A detailed explanation of implementation api embed
- Open Office XML 格式里如何描述多段具有不同字体设置的段落
- 2022 Recruitment Notice for Academician Zhao Guoping Group of Shenzhen Institute of Advanced Technology, Chinese Academy of Sciences
- C# WPF image is displayed without problems, but the solution does not display the image at runtime
- MYSQL误删数据恢复
- 2022-08-09: What does the following go code output?A: No, it will panic; B: Yes, it can run correctly; C: Not sure, see the voting result.package main import (“fmt“ “syn
- 雨水中存在的PFAS化学物质对饮用水安全构成了威胁
- 汉字检测和关键词检测
- 2022-08-09:以下go语言代码输出什么?A:否,会 panic;B:是,能正确运行;C:不清楚,看投票结果。 package main import ( “fmt“ “syn
- Makefile missing separator. Stop.怎么解决「建议收藏」
猜你喜欢

专有云ABC Stack,真正的实力派!

A unit test report for CRM One Order Application log

【黑马早报】雷军称低谷期曾想转行开酒吧;拜登正式签署芯片法案;软银二季度巨亏230亿美元;北京市消协约谈每日优鲜...

代码随想录笔记_动态规划_70爬楼梯

Basic knowledge of switches

表中存在多个索引问题? - 聚集索引,回表,覆盖索引

【ECCV 2022|Millions of Prizes】PSG Competition: Pursuing the "Most Comprehensive" Scene Understanding

kubernetes介绍

Jenkins修改端口号, jenkins容器修改默认端口号

【量化交易行情不够快?】一文搞定通过Win10 wsl2 +Ubuntu+redis+pickle实现股票行情极速读写
随机推荐
shell:正则表达式及三剑客grep命令
【ECCV 2022|Millions of Prizes】PSG Competition: Pursuing the "Most Comprehensive" Scene Understanding
交换机的基础知识
高数_证明_弧微分公式
Detailed explanation of es6-promise object
Merge similar items in LeetCode simple questions
想通这点,治好 AI 打工人的精神内耗
YTU 2295: KMP模式匹配 一(串)
指针(C语言初解)
没有接班人,格力只剩“明珠精选”
AWS 安全基础知识
A unit test report for CRM One Order Application log
Jenkins修改端口号, jenkins容器修改默认端口号
Loudi Cosmetics Laboratory Construction Planning Concept
G1和CMS的三色标记法及漏标问题
3DS MAX 批量导出文件脚本 MAXScript 带界面
BEVDet4D: Exploit Temporal Cues in Multi-camera 3D Object Detection Paper Notes
M²BEV: Multi-Camera Joint 3D Detection and Segmentation with Unified Bird’s-Eye View Representation
Code Casual Recording Notes_Dynamic Programming_70 Climbing Stairs
ArcMAP has a problem of -15 and cannot be accessed [Provide your license server administrator with the following information:Err-15]