Promise原理解析,使用ES5实现Promise
Promise
js的单线程特性导致大量的异步操作,异步操作我们通常使用函数回调的方式实现。大量的函数回调会产生我们的毁掉地狱,降低代码的可读性和可维护性。
为了解决这些问题,先后出现了Promise函数、Generator函数和async函数。目前Promise配合async/await成为了主流。
Promise本质上并没有改变异步操作,只是让我们可以用同步的代码写法去书写异步操作。增加代码的可读性。
Promise是ES6中确定的,今天我们就使用ES5的写法,手动实现自己的Promise,以求彻底掌握Promise的核心原理。今天我们只封装实现Promise的基本功能。
先看一下在ES6中我们是如何使用Promise的
let promiseFn = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(111)
}, 1000)
});
promiseFn.then(res => {
console.log(res) // res === 111
})// 使用async/await
async function promiseFn () {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(111)
}, 1000)
})
}
let res = await promiseFn() // res === 111
Promise规范 Promise规范的原文地址
Promise规范的中文翻译地址
里面详细介绍了Promise的各种术语、定义和规范。其中最需要理解的就是Promise的三种状态以及其中的状态变化。“等待态(Pending)、执行态(Fulfilled)和拒绝态(Rejected)”。
状态改变不可逆,只能Pending --> Fulfilled 或者 Pending --> Rejected
文章图片
WX20190620-174026@2x.png 预备 使用status存储Promise状态(pending、fulfilled、rejected)
使用value存储resolve的数据
使用err存储reject的错误信息
使用原型链继承的方式创建then函数
使用onFulfilledArr存储将要执行的resolve函数
使用onRejectedArr存储将要执行的reject函数
创建 MyPromise构造函数
// 创建 MyPromise构造函数
function MyPromise (fn) {
let self = this;
this.value = https://www.it610.com/article/null;
// 存储resolve数据
this.status ='pending';
// 存储状态
this.err = null;
// 存储reject错误信息
this.onFulfilledArr = [];
// 存储将要执行的resolve函数
this.onRejectedArr = [];
// 存储将要执行的reject函数
function resolveFn (val) { // resolve()时执行的函数
if (self.status === 'pending') { // 只用pending状态才能继续进行
self.value = https://www.it610.com/article/val;
// 存储数据
self.status ='fulfilled';
// 改变状态
// 逐个调用then()函数
self.onFulfilledArr.forEach(function(thenFn) {
thenFn(self.value);
});
}
}
function rejectFn(errMsg) { // reject()时执行的函数
if (self.status === 'pending') {
self.err = errMsg;
self.status = 'rejected';
self.onRejectedArr.forEach(function(catchFn) {
catchFn(self.err);
});
}
}
try {
fn(resolveFn, rejectFn);
} catch (e) {
rejectFn(e);
}
}
实现then()函数 创建好了Promise构造函数下一步创建then()函数
MyPromise.prototype.then = function(onFulfilled, onRejected) {
// 如果当前处于pending状态,就将函数压入对应数组
var self = this;
if (self.status === 'pending') {
self.onFulfilledArr.push(onFulfilled);
self.onRejectedArr.push(onRejected);
}
// fulfilled状态就执行onFulfilled()方法
if (self.status === 'fulfilled') {
onFulfilled(self.value);
}
// onFulfilled状态就要执行onRejected()函数
if (self.status === 'rejected') {
onRejected(self.err);
}
return this;
// return this是链式调用关键
};
【Promise原理解析,使用ES5实现Promise】到此我们就实现了自己的myPromise()方法。最关键的还是Promise的三种状态,理解了三种状态的切换就基本掌握了Promise。
推荐阅读
- 做一件事情的基本原理是什么()
- 【读书笔记】贝叶斯原理
- SG平滑轨迹算法的原理和实现
- “写作宝典”《金字塔原理》之读书笔记
- Quartz|Quartz 源码解析(四) —— QuartzScheduler和Listener事件监听
- Java内存泄漏分析系列之二(jstack生成的Thread|Java内存泄漏分析系列之二:jstack生成的Thread Dump日志结构解析)
- [源码解析]|[源码解析] NVIDIA HugeCTR,GPU版本参数服务器---(3)
- Android系统启动之init.rc文件解析过程
- Spring|Spring 框架之 AOP 原理剖析已经出炉!!!预定的童鞋可以识别下发二维码去看了
- Spring|Spring Boot 自动配置的原理、核心注解以及利用自动配置实现了自定义 Starter 组件