手写实现Promise源码
/ / 点击 / 阅读耗时 5 分钟很多大厂面试的时候会问到如何实现Promise,出于对Promise内部底层实现原理的探知。自己通过搜集一些资料,从一开始模仿着实现。到最后控制台调试以及逐行代码阅读理解,算是搞清楚了Promise实现原理。
原生Promise
在手写Promise之前肯定要了解原生Promise究竟是怎样使用,然后再一步步模拟实现,首先来个原生Promise的例子:
new Promise((resolve,reject)=>{
//模拟异步
setTimeout(()=>{
resolve('Promise')
},1000)
}).then(res=>{
console.log(res) //1秒后输出Promise
},err=>{
//异常情况
})
可以根据Promise写法来推断实现原理:
- 首先通过new Promise构造函数,生成Promise对象(实例)。Promise构造函数中传入一个函数,传入的函数中包含两个参数,他们分别也是函数。
- 在Promise传入的函数内部执行异步代码,异步代码体内执行完成逻辑之后调用resolve函数,最终把异步结果通过resolve传递出去。
- 通过new Promise生成的Promise对象会有个then方法,then方法里面也有两个参数,分别代表成功和异常的回调函数(有顺序)。
简易版的Promise
function _Promise(executor){
let self = this;
self.status = 'pending' //初始化Promise状态
self.value = '' //存储Promise成功/失败回调的值
self.onResolvedCallBacks = []; //存储Promise resolve成功回调函数集
self.onRejectedCallBacks = []//存储Promise reject失败回调函数集
//resolve成功回调
function resolve(){
}
//reject异常回调
function reject(){
}
executor(resolve,reject) //执行传入的回调并传入相应的参数
}
以上是_Promise构造函数主体,接下来我们就要填充resolve、reject函数,然后再做一些优化
function _Promise(executor){
let self = this;
self.status = 'pending' //初始化Promise状态
self.value = '' //存储Promise成功/失败回调的值
self.onResolvedCallBacks = []; //存储Promise resolve成功回调函数集
self.onRejectedCallBacks = []//存储Promise reject失败回调函数集
//resolve成功回调
function resolve(value){
if(self.status == 'pending'){
self.status = 'resolved';
self.value = value;
for (let i = 0; i < self.onResolvedCallBacks.length; i++) {
self.onResolvedCallBacks[i](value);
}
}
}
//reject异常回调
function reject(err){
if(self.status == 'pending'){
self.status = 'rejected';
self.value = err;
for (let i = 0; i < self.onRejectedCallBacks.length; i++) {
self.onRejectedCallBacks[i](err);
}
}
}
//为了考虑执行executor的过程中可能会有异常情况,所以我们就用try和catch包裹起来
try{
executor(resolve,reject) //执行传入的回调并传入相应的参数
}catch(err){
reject(err)
}
}
Promise构造函数内部逻辑基本上就是判断状态为pending之后把状态改为相应的值,然后把resolve和reject对应的参数存在self.value上。之后执行相应的回调。
之后就是then方法的实现,我们把then方法挂到原型上
_Promise.prototype.then = function(onResolved,onRejected){
let self = this;
onResolved = typeof onResolved == 'function' ? onResolved : function(res){}
onRejected = typeof onRejected == 'function' ? onRejected : function(err){}
if(self.status == 'pending'){
self.onResolvedCallBacks.push(onResolved)
self.onRejectedCallBacks.push(onRejected)
}
if(self.status == 'resolved'){
onResolved(self.value)
}
if(self.status == 'rejected'){
onRejected(self.value)
}
}
最后测试下代码:
new _Promise(resolve=>{
setTimeout(()=>{
resolve('hello Promise')
},2000)
}).then(res=>{
console.log('res 的值是:',res); // 2s后执行 res 的值是 'hello Promise'
})
全文完。