手写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)
            })
        }
    });
}

全部评论

相关推荐

美团数开日常实习两个月有感不知不觉,我在美团数开日常实习已经满两个月啦!组内氛围真的超级棒!大家亲如一家,每天中午都聚在一起吃饭,边吃边聊,其乐融融。饭后,还会结伴去楼下散步,呼吸新鲜空气,放松身心。而且,组里作息很规律,基本到下班时间大家都会准时离开,很少有人加班。即便偶尔有事需要加班,MT&nbsp;和&nbsp;LD&nbsp;也会贴心地提醒我早点回家,让我时刻感受到家一般的温暖与关怀。工作内容丰富又充实,每一个需求都是一次全新的挑战与成长机会。我能够真实地和需求方面对面交流,这种直接的沟通方式,不仅让我在技术层面有了质的飞跃,更在人际交往、职场交流等方面得到了极大的锻炼。值得一提的是,我这个曾经的&nbsp;I&nbsp;人,现在经过这段时间的历练,测试下来已经成功变身&nbsp;E&nbsp;人啦。美团的饭堂简直太大了,走进去就像进入了一个美食天堂。各色菜式应有尽有,色香味俱全,让人每天都能享受到美味佳肴。而且,周边饭店众多,身为美团员工,还能享受各种折扣优惠,这可真是实实在在的福利呀!每天&nbsp;8&nbsp;点还有&nbsp;30&nbsp;元的餐补,不仅可以用来在饭堂大快朵颐,还能在小象超市购买心仪的商品,甚至点外卖也是极好的选择。尤其是现在&nbsp;2&nbsp;元就能买到&nbsp;40&nbsp;张的外卖券,简直不要太划算,想怎么“膨胀”就怎么“膨胀”!总的来说,这两个月的实习&nbsp;landing&nbsp;非常顺利!我收获了知识、技能,更收获了珍贵的友谊与成长。展望未来,我希望能继续保持这份充实与快乐,不断突破自我,创造更多佳绩。当然,最大的心愿还是秋招能够顺利转正,继续在美团这个大家庭里发光发热,开启属于自己的精彩职场旅程!#美团实习# #美团工作体验#
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务