从简开始,逐步深入 写一个自己的Promise
- 一、分析Promise。
- step one:分析使用
- step tow:分析原理
- step three:编写
- 未完待续....
一、分析Promise。
step one:分析使用
先看看Promise的一个简单使用过程(如下代码):通过new关键字创建Promise对象,初始化时传入一个需要执行的函数,该函数有两个方法参数,分别是成功时需要调用的方法resolve,用于触发之后的成功回调;和失败时要调用的方法reject,用于触发后面的失败回调。此时new Promise(…)语句成功创建了一个Promise实例对象,这个实例对象里面有个then方法,里面传入两个回调函数参数,一个是成功的回调函数,一个是失败回调。
new Promise((resolve,reject)=>{
if(/*成功*/){
//成功调用resolve,并传入结果
resolve('success')
}else{
//失败则调用reject方法,并传入信息
reject('fail')
}
}).then(functino(res){
//成功回调
},function(err){
//失败回调
})
step tow:分析原理
由上面的使用可以得出,Promise本质上是一个构造函数,初始化对象时传入一个需要执行的函数参数,这个函数里有两个resolve和reject,分别用于触发成功回调和失败回调。promise实例对象上有一个then方法用于注册成功时需要执行的事件和失败时需要执行的事件。
深剖一下,Promise一共有三个状态,分别是pending、resolve(fulfilled)、rejected,分别表示等待状态、成功状态、失败状态,状态的转换只能由pending状态到余下的两个状态,且不可逆,一但状态改变就不会在变,这意味着,之前的resolve函数和rejet函数其中一个执行了,后面语句中如果再次调用了没有意义,不会有什么结果,这一点大家亲自试一下就知道了。
step three:编写
好,理论有了,开始根据理论编写代码
const { rejects } = require("assert");
//promise的三个状态
const PENDING='pending';
const FULFILLED='fulfilled';
const REJECTED='rejected';
//创建IPromise构造函数,execute为被执行的函数
function IPromise(execute){
//promise的状态
this.state=PENDING;
//成功回调函数和失败回调函数默认为空,这里目前暂时直接用变量存储,后期这里需要用数组存储,因为这里应该要是一个待执行的事件列表,细节在之后的分析中解释,现在先不用理会这个概念,我们一步一步来。
this.successCallback=null;
this.failCallback=null;
//触发成功回调的函数
let resolve=(res)=>{
//如果状态还处于pending状态,则将状态改为fulfilled状态,如果已经不是pending状态,根据原Promise的特性,无法在改变,所以直接return退出
if(this.state==PENDING){
this.state=this.FULFILLED;
}else{
return;
}
//由于Promise的成功回调是异步的,所以用setTimeout来使其从同步变为异步
setTimeout(()=>{
if(this.successCallback){
this.successCallback(res);
}
})
}
//用于触发失败回调的函数
let reject=(err)=>{
//同理
if(this.state==PENDING){
this.state=this.REJECTED;;
}else{
return;
}
//setTimeout与上面同理
setTimeout(()=>{
if(this.failCallback){
this.failCallback(err);
}
})
}
//注册失败与成功的回调事件的函数
this.then=(successCallback,failCallback)=>{
this.successCallback=successCallback;
this.failCallback=failCallback;
}
//一切准备就绪,开始执行,这里还要做一下try catch处理,防止待执行的函数里有报错,中断函数的执行,要严谨。
try{
execute(resolve,reject);
}catch(e){
//报错的化直接调用这个函数执行错误回调。
rejects(e)
}
}
未完待续…