JS中Promise的简单实现
什么是Promise
简单点来说就是异步,存在的意义在于将多级嵌套的异步调用(回调地狱)变为链式结构来处理,这篇博文主要说一个自己的简单实现思路。(有不对的请指正)
Promise简单实例
下面是一个简单的Promise实例
new Promise((resolve, reject) => {
setTimeout(() => {
resolve(2333)
}, 2000)
}).then(res => {
console.log(res)
})
分析
- Promise的构造函数参数为一个包含两个参数的函数,即
function fn(resolve, reject) {}
- Promise有一个then方法,then方法的参数是两个函数,在js中即
Promise.prototype = function then(resCallback, errCallback){}
- Promise 需要有一个变量去保存
resolve(val)
或者reject(val)
中调用的参数val - Promise本身有三个状态
pending、fulfilled、rejected
,需要有一个变量_status
去储存状态(pending表示正在等待调用,fulfilled表示调用成功,rejected表示调用失败,主要为了在then方法中判断应该调用哪种回调函数)
可以看出Promise的本质实际是个回调函数,下面一步一步来分析Promise的内部基本构造
// 构造函数
// fn : function fn(resolve, reject){ ...some code }
function _promise(fn) {
let _self = this;
this._value; // undefined 保存resolve(val)或者reject(val)中调用的参数val
this._status = "pending"; // 保存promise的状态
let _resolve = function(val) {
if(_self._status !== "pending") return; // promise的状态是单向的
_self._status = "fulfilled"; //调用_resolve表示操作成功
_self._value = val; // 保存val 方便在then中调用
}
let _reject = function(val) {
if(_self._status !== "pending") return; // promise的状态是单向的
_self._status = "rejected"; //调用_reject表示操作失败
_self._value = val;
}
fn(_resolve, _reject); //回调
}
_promise.prototype.then = function (onFulfilled, onRejected){
onFulfilled && onFulfilled(this._value);
onRejected && onRejected(this._value);
}
new _promise((resolve, reject) => {
resolve(2333);
}).then(res => {
console.log("这里是自定义_promise:", res);
})
基本思路上面的已经完成,但是还有两个大问题:
- 不支持链式调用(因为_promise中只定义了一个_value,只支持then方法中处理一次回调)
- 没有实现异步功能
基本功能实现(为链式调用的实现做准备)
定义两个数组onResolvedCallback
和 onRejectedCallback
来存放所有then中的回调函数,在then中将回调函数保存在数组中,那在什么时候调用呢?仔细想想,其实onResolvedCallback
和 onRejectedCallback
是在_resolve/_reject
后调用的,于是思路清晰了,先在then
中定义一个回调函数,然后在_resolve/_reject
中进行调用。
function _promise(fn) {
let _self = this;
this._value;
this._status = "pending";
/-- 增加两个变量来存放then中的callback --/
this.onResolvedCallback = [];
this.onRejectedCallback = [];
let _resolve = function(val) {
if(_self._status !== "pending") return;
_self._status = "fulfilled";
_self._value = val;
/-- 在这里调用callback,不管后面的链式调用中有多少个then,这里都是按顺序执行 --/
for(let i=0; i<_self.onResolvedCallback.length; i++) {
_self.onResolvedCallback[i](val)<