手写Promise

要看完整代码直接拉到最下方即可

(1).初始结构搭建与resolve,reject结构搭建

//声明构造函数 Promise对象有两个属性一个PromiseState 一个PromiseResult
function Promise(executor){
  //声明属性
  	this.PromiseState='pending'
  	this.PromiseResult=null
  //保存实例对象的this
  	const self=this
  //在resolve方法中我们要改变Promise对象状态,改变PromiseResult
  function resolve(data){
	self.PromiseState='fulfilled'
	self.PromiseResult=data
  }
  //同理
  function rejected(data){
	if(self.PromiseState!=='pending') return
	self.PromiseState='rejected'
	self.PromiseResult=data
  }
    //同步调用[执行器函数]
  executor(resolve,reject)
}
//添加then方法
Promise.prototype.then=function(onResolved,onRejected){
}

(2).throw抛出异常改变状态

function Promise(executor){
	this.PromiseState='pending'
  	this.PromiseResult=null
  	const self=this
	function resolve(data){
	  self.PromiseState='fulfilled'
	  self.PromiseResult=data
	}
  	function reject(data){
	  self.PromiseState='rejected'
	  self.PromiseResult=data
	}
  //在执行器函数 throw抛出异常想到用try...catch;
 try{
 	executor(resolve,reject)
 }catch(e){
   //修改promise对象的状态为失败
   reject(e)//为什么是e不是data了?因为结果值就是抛出的结果值
 	}
}
Promise.prototype.then=function(onResolved,onRejected){
}

(3)Promise对象状态只能改变一次以及then方法执行回调

function Promise(executor){
  this.PromiseState='pending'
  this.PromiseResult=null
  const self=this
  function resolve(data){
	//判断状态
	if(self.PromiseState!=='pending')return
	self.PromiseState='fulfilled'
	self.PromiseResult=data
  }
  function reject(data){
	if(self.PromiseState!=='pending')return
	self.PromiseState='rejected'
	self.PromiseResult=data
  }
  try{
	executor(resolve,reject)
  }catch(e){
  	reject(e)
  }
}
Promise.prototype.then=function(onResolved,onRejected){
  //调用回调函数
  if(this.PromiseState==='fulfilled){
	 //因为这里是实例对象调用的所以直接用this就行
	 onResolved(this.PromiseResult)
	}
	if(this.PromiseState==='rejected'){
	  onRejected(this.PromiseResult)
	}
}

(4)异步任务回调的执行

function Promise(executor){
  	this.PromiseState='pending'
  	this.PromiseResult=null
  	const self=this
	//声明属性
	this.callback={}
  	function resolve(data){
	  	if(self.PromiseState!=='pending')return
		self.PromiseState='fulfilled'
	  	self.PromiseResult=data
	  //调用成功的回调函数
	  if(self.callback.onResolved){
		self.callback.onResolved(data)
	  }
	}
  	function reject(data){
	  	if(self.PromiseState!=='pending')return
	  	self.PromiseState='rejected'
	  	self.PromiseResult=data
	  //调用失败的回调
	  if(self.callback.onRejected){
		self.callback.onRejected(data)
	  }
}
  try{
  	executor(resolve,reject);
  }catch(e){
	resolve(e)
  }
Promise.prototype.then=function(onResolved,onRejected){
  	if(this.PromiseState==='fulfilled'){
	 onResolved(this.PromiseResult)
	}
	if(this.PromiseState === 'rejected'){
	 onRejected(this.PromiseResult)
	}
  	if(this.PromiseState==='pending'){
	  //保存回调函数
	  this.callback={
	  	onResolved:onResolved
		onRejected:onRejected
	  }
	}
}

(5)指定多个回调的实现

function Promise(executor){  
  this.PromiseState='pending';  
  this.PromiseResult=null;  
  const self=this;  
  //this.callback={}; //这样保存有个弊端,后面的回调函数会把它覆盖掉
  this.callbacks=[]
  function resolve(data){  
    if(self.PromiseState!=='pending') return;  
    self.PromiseState='fulfilled';  
    self.PromiseResult=data;  
    /**if(self.callback.onResolved){  
      self.callback.onResolved(data);  
    }*/
	//遍历
	self.callbacks.forEach(item=>{
		item.onResolved(data)
	})
  }  
  
  function reject(data){ 
    if(self.PromiseState!=='pending') return; 
    self.PromiseState='rejected';  
    self.PromiseResult=data;  
    /**if(self.callback.onRejected){  
      self.callback.onRejected(data);  
    }*/
	self.callbacks.forEach(item=>{
	  item.onRejected(data)
	})
  }  
  
  try{  
    executor(resolve, reject);  
  }catch(e){  
    reject(e);  
  }  
}  
  
Promise.prototype.then=function(onResolved,onRejected){  
  if(this.PromiseState==='fulfilled'){ 
    onResolved(this.PromiseResult);  
  } else if(this.PromiseState==='rejected'){ 
    onRejected(this.PromiseResult);  
  }  
  if(this.PromiseState==='pending'){  
    this.callbacks.push({  
      onResolved:onResolved, 
      onRejected:onRejected  
    })  
  }  
}; 

(6)同步修改then方法和异步修改then方法 结果返回

这里我一开始犯了个错误,想着在执行器函数中写过try...catch捕获错误了,不用再在then方法中捕获。其实是不对的,因为执行器函数中的try...catch是用来捕获在初始化解析或拒绝状态时可能发生的错误。then方法中的try...catch则是用来捕获onResolved或onRejected回调函数中可能抛出的异常。这些异常通常发生在Promise已经解析或拒绝之后,注册新的回调函数并执行他们。

function Promise(executor){
	this.PromiseState='pending'
  	this.PromiseResult=null
  	const self=this
	const callbacks=[]
function resolve(data){
  if(self.PromiseState!='pending) return
	 self.PromiseState='fulfilled'
	 self.PromiseResult=data
	 self.callbacks.forEach(item=>{
	 	item.onResolved(data)
	})
}
function reject(data){
  if(self.PromiseState!='pending)
	self.PromiseState='rejected'
	self.PromiseResult=data
	self.callbacks.forEach(item=>{
	 item.onRejected(data)
	})
}
    try{
	executor(resolve,reject)
  }catch(e){
	reject(e)
  }
}
Promise.prototype.then(onResolved,onRejected){
  const self=this
  //返回一个新的Promise对象
  return new Promise((resolve,reject)=>{
  if(this.PromiseState==='fulfilled'{
	 //获取回调函数的执行结果
	 try{
	 let result=onResolved(this.PromiseResult)
	//判断执行结果是否为一个Promise对象
	if(result instanceof Promise){
	  result.then(v=>{
			resolve(v)
	  },r=>{
			reject(r)
	  })
		}else{
		  //结果对象的状态为成功
				resolve(result)
		}
  }catch(e){
		reject(e)
  }
	}
	if(this.PromiseState==='rejected'{
	 onRejected(this.PromiseResult)
	}
	if(this.PromiseState==='pending'{
		this.callbacks.push({
	   		onResolved:function(){
	  //判断
	  try{
		//执行成功的回调函数
	  let result=onResolved(self.PromiseResult)
	  if(result instance of Promise){
	  	result.then(v=>{
		  resolve(v)
		},r=>{
		  reject(r)
		})
	  }else{
			resolve(v)
	  }
	  }catch(e){
		reject(e)
	  }
	},
	   		onRejected:function(){
			  try{
	//执行失败的回调函数
		let result = onRejected(self.PromiseResult)
	  if(result instance of Promise){
	  	result.then(v=>{
		  resolve(v)
		},r=>{
		  reject(r)
		})
	  }else{
			resolve(v)
	  }
	  }catch(e){
		reject(e)
	  }  
			}
		}) 
	}
})
}

(7)完善then方法

从上面的代码中看出来,有很多重复的代码,为了简洁,我们将它进行封装

function Promise(executor){
  this.PromiseState='pending'
  this.PromiseResult=null
  const self=this
  const callbacks=[]
  function resolve(data){
	if(self.PromiseState!='pending')return
	self.PromiseState='fulfilled'
	self.PromiseResult=data
	self.callbacks.forEach(item=>{
		item.onResolved(data)
	})
  }
  function reject(data){
	if(self.PromiseState!='pending')return
	self.PromiseState='rejected'
	self.PromiseResult=data
	self.callbacks.forEach(item=>{
	  item.onRejected(data)
	})
  }
  try{
	executor(resolve,reject)
  }catch(e){
	reject(e)
  }
}
Promise.prototype.then=function(onResolved,onRejected){
  const this=self
  return new Promise((resolve,reject)=>{
	//封装函数
	function callback(type){
		let result=type(self.PromiseResult)
		try{
		if(result instanceof Promise){
			result.then(v=>{
			  resolve(v)
			},r=>{
			  reject(r)
			}else{
					resolve(result)
		}
		}catch(e){
					reject(e)
		}
	}
  	if(this.PromiseState==='fulfilled'){
		callback(onResolved)
	}
	if(this.PromiseState==='rejected'){
		callback(onRejected)
	}
	if(this.PromiseState==='pending'){
		this.callbacks.push({
		onResolved:function(){
			callback(onResolved)
		},
		onRejected:function(){
			callback(onRejected)
		}
		})
	}
  })
}

(8)catch方法的封装我们要实现两个功能:1.catch传统2.值传递;resolve方法的封装

function Promise(executor){
  this.PromiseState='pending'
  this.PromiseResult=null
  const self=this
  const callbacks=[]
  function resolve(data){
	if(self.PromiseState!='pending')return
	self.PromiseState='fulfilled'
	self.PromiseResult=data
	self.callbacks.forEach(item=>{
		item.onResolved(data)
	})
  }
  function reject(data){
	if(self.PromiseState!='pending')return
	self.PromiseState='rejected'
	self.PromiseResult=data
	self.callbacks.forEach(item=>{
	  item.onRejected(data)
	})
  }
  try{
	executor(resolve,reject)
  }catch(e){
	reject(e)
  }
}
Promise.prototype.then=function(onResolved,onRejected){
  const this=self
  //判断回调函数
  if(typeof onRejected !=='function'){
	onRejected=reason=>{
	  throw reason
	}
	if(typeof onResolved !=='function'){
	  onResolved=value=>value
	}
  return new Promise((resolve,reject)=>{
	function callback(type){
		let result=type(self.PromiseResult)
		try{
		if(result instanceof Promise){
			result.then(v=>{
			  resolve(v)
			},r=>{
			  reject(r)
			}else{
					resolve(result)
		}
		}catch(e){
					reject(e)
		}
	}
  	if(this.PromiseState==='fulfilled'){
		callback(onResolved)
	}
	if(this.PromiseState==='rejected'){
		callback(onRejected)
	}
	if(this.PromiseState==='pending'){
		this.callbacks.push({
		onResolved:function(){
			callback(onResolved)
		},
		onRejected:function(){
			callback(onRejected)
		}
		})
	}
  })
}
//封装catch方法
Promise.prototype.catch=function(onRejected){
  return this.then(undefind,onRejected)
}
  //封装resolve方法
Promise.resolve=function(value){
  //返回promise对象
  return new Promise((resolve,reject)=>{
	if(value instanceof Promise){
	  value.then(v=>{
		resolve(v)
	  },r=>{
		reject(r)
	  })
	}else{
	  //状态设置成功
	  resolve(value)
	}
  })
}
//封装reject方法
Promise.reject=function(reason){
  return new Promise((resolve,reject)=>{
  	reject(reason)
  })
}
  //封装all方法
Promise.all=function(promises){
	return new Promise((resolve,reject)=>{
	  let count=0
	  let arr=[]
	  //遍历
	  for(let i=0;i<promises.length;i++){
		promises[i].then(v=>{
		  //得知对象状态是成功的
		  //每个promise对象都成功
		  count++;
		  //将当前promise对象成功的结果存入数组当中
		  arr[i]=v
		  //判断
		  if(count ===promises.length){
			resolve(arr)  
			}
	  },r=>{
		  reject(r)
		})
	  }
	})
}
//封装race方法
Promise.race=function(promises){
	return new Promises((resolve,reject)=>{
		for(int i=0;i<promises.length;i++){
			promises[i].then(v=>{
			  resolve(v)
			},r=>{
			  reject(r)
			})
		}
	})
}

(9)then方法回调的异步执行 完结


//1.声明构造函数
function Promise(excutor){
    //5.添加属性
    this.PromiseState='pending'
    this.PromiseResult=null
    //声明属性
    this.callbacks=[]
    //保存实例对象的this
    const self=this

    //4.声明resolve,reject
    function resolve(data){
        //判读状态
        if(self.PromiseState!=='pending') return
        //4.1 修改对象的状态(PromiseState)
        self.PromiseState='fulfilled'
        //4.2 设置对象结果值(PromiseResult)
        self.PromiseResult=data
        //调用成功的回调函数 ???
        setTimeout(()=>{
        self.callbacks.forEach(item => {
            item.onResolved(data)
        })
    })
    }
    function reject(data){
        if(self.PromiseState!=='pending') return
        self.PromiseState='rejected'
        self.PromiseResult=data
        setTimeout(()=>{
        self.callbacks.forEach(item => {
            item.onRejected(data)
        });
    })
    }
    try{
    //3.执行器函数同步调用
    excutor(resolve,reject);
    }catch(e){
        //修改Promise对象状态为[失败]
        reject(e);
    }
}
//2.添加then方法
Promise.prototype.then=function(onResolved,onRejected){
    const self=this;
    //判断回调函数参数
    if(typeof onRejected !=='function'){
        onRejected=reason=>{
            throw reason
        }
    }
    if(typeof onResolved!=='function'){
        onResolved=value=>value //简略写法
        //value => {return value}
    }
    return new Promise((resolve,reject)=>{
    //封装函数
    function callback(type){
        try{
            //获取回调函数的执行结果
        let result = type(self.PromiseResult)
            //判断如果回调函数的结果是Promise对象
            if(result instanceof Promise){
                //如果是Promise对象
                result.then(v=>{
                    resolve(v);
                },r=>{
                    reject(r);
                })
            }else{
                resolve(result)
            }
        }catch(e){
                reject(e)
            }
        }
    //调用回调函数
    if(this.PromiseState==='fulfilled'){
        setTimeout(()=>{
        callback(onResolved)
    })
    }
    if(this.PromiseState==='rejected'){
        setTimeout(()=>{
       callback(onRejected)
    })
    }
    //判断pending状态
    if(this.PromiseState==='pending'){
        //保存回调函数
        this.callbacks.push({
            onResolved:function(){
                callback(onResolved)
            },
            onRejected:function(){
                callback(onRejected)
            }
        })
    }
    })

}

//添加catch方法
Promise.prototype.catch=function(onRejected){
    return this.then(undefined,onRejected)
}

//添加resolve方法
Promise.resolve=function(value){
//返回promise对象
    return new Promise((resolve,reject)=>{
        if(value instanceof Promise){
            value.then(v=>{
                resolve(v)
            },r=>{
                reject(r)
            })
        }else{
            resolve(value);
        }
    })
}

//添加reject方法
Promise.reject=function(reason){
    return new Promise((resolve,reject)=>{
        reject(reason)
    })
}

//添加all方法
Promise.all=function(promises){
    //返回结果为Promise对象
    return new Promise((resolve,reject)=>{
        //声明变量
        let count=0;
        let arr=[];
        //遍历
        for(let i=0;i<promises.length;i++){
            //
            promises[i].then(v=>{
                //得知对象的状态是成功的
                //每个promise对象都成功
                count++;
                //将当前的promise对象成功的结果存入到数组中
                arr[i]=v;
                if(count===promises.length){
                    resolve(arr);
                }
            },r=>{
                reject(r);
            })
        }
    })
}

//添加race方法
Promise.race=function(promises){
    return new Promise((resolve,reject)=>{
        for(let i=0;i<promises.length;i++){ 
            promises[i].then(v=>{
                resolve(v);
            },r=>{
                reject(r)
            })
        }
    });
}

全部评论

相关推荐

不愿透露姓名的神秘牛友
07-08 14:08
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务