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
Promise原理解析,使用ES5实现Promise
文章图片
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。

    推荐阅读