想要学会一个东西,那就去实现它。name要学会promise,那就去实现一个promise。没毛病吧,那么接下来我们就来实现一个myPromise。
首先我们知道promise有三种状态以及返回结果,所以有
class myPromise{
constructor(){
this.state = 'pending'
this.result = null
}
}
然后两个方法,接收值,并且状态只能改变一次
class myPromise{
constructor(ext){
this.state = 'pending'
this.result = null
ext(this.resolve, this.reject)
}
resolve(val){
if(this.state !== 'pending') return
this.state = 'onFullfilled'
this.result = val
}
reject(val){
if(this.state !== 'pending') return
this.state = 'rejectd'
this.result = val
}
}
但是此时问题来了,首先是this指向问题,因为是方法传过来的所以访问会出现this值为undefined的情况,所以需要修改this的指向
class myPromise{
constructor(ext){
this.state = 'pending'
this.result = null
this.resolve = this.resolve.bind(this)
this.reject = this.reject.bind(this)
ext(this.resolve, this.reject)
}
resolve(val){
if(this.state !== 'pending') return
this.state = 'onFullfilled'
this.result = val
}
reject(val){
if(this.state !== 'pending') return
this.state = 'rejectd'
this.result = val
}
}
此时constructor的当中就会显的比较冗余,所以对此进行一个简单的封装操作。如下
class myPromise{
constructor(ext){
this.initVal()
this.initBind()
ext(this.resolve, this.reject)
}
initVal(){
this.state = 'pending'
this.result = null}
initBind(){
this.resolve = this.resolve.bind(this)
this.reject = this.reject.bind(this)}
resolve(val){
if(this.state !== 'pending') return
this.state = 'onFullfilled'
this.result = val
}
reject(val){
if(this.state !== 'pending') return
this.state = 'rejectd'
this.result = val
}
}
此时一个简单的promise就封装好了,来看一下效果吧
let myPro = new myPromise((resolve, reject) => {
resolve(1);
});
name想要获取myPromise的返回值需要怎么办呢?此时需要在封装一个.then方法,如下:
myPromise.prototype.then = function(onFullfilled, onReject){
// 先判断是否是一个函数
onFullfilled = typeof onFullfilled === "function" ? onFullfilled : (val) => val
onRejectd = typeof onFullfilled === "function" ? onFullfilled : (reason) => {
throw reason
}
// 在这里面的this是调用的myPromise对象,所以可以获取到这个myPromise的所有属性,可以参考上图
if(this.state === "onFullfilled"){
onFullfilled(this.result)
}else {
onRejectd(this.result)
}
}
此时就可以获取到myPromise想要返回的值了,如下图:
但是有个问题,只能执行一次.then操作,后续会报错。
如果想要实现链式调用,非常简单,只需要在.then当中添加一行代码即可。但是真正的promise对象仅第一次会拿到返回值,接下来的.then拿到的都是undefined,所以还需在添加一句代码,将this.result赋值为undefined即可。
myPromise.prototype.then = function (onFullfilled, onRejectd) {
onFullfilled =
typeof onFullfilled === "function" ? onFullfilled : (val) => val;
onRejectd =
typeof onRejectd === "function"
? onRejectd
: (reason) => {
throw reason;
};
if (this.state === "fullfilled") {
onFullfilled(this.result);
} else if (this.state === "rejectd") {
onRejectd(this.result);
}
this.result = undefined;
return this;
};
靓仔靓女,代码到这里也就结束了,如果感觉有点收获的话,就给个赞吧~