JSPromise async await

Promise.js


/*
 *自定义模块 :函数
 * */


;(function (params){
	
	
	//传入一个执行器:同步执行
	/*
	 	new Promise((resolve,reject)=>{
	 		resolve(1)//成功
	 		reject('失败')
	 	})
	 * */
	//调用执行器之前,要准备用于改变promise状态的函数
	function Promise(executor){
		//这个that 在当前函数作用域里面保存
		const that = this //先保存 
		that.status = 'pending' //给promise对象指定status属性,初始值为pending
		that.data = undefined   //给promise对象指定一个用于存储数据的属性 ===外面传递过来的
		that.callbacks = []     //每个元素的构造 {onResolved=>{},onRejected=>{}}
		
		
		//立即执行执行器 同步
		function resolve(value){
			//状态只能改变一次
			if(that.status !== 'pending'){
				return 
			}
			
			
			//将状态改为resolved
			that.status = 'resolved'
			
			//保存value数据
			that.data = value
			
			//如果有待执行的callback函数,立即 异步执行回调函数
			if(that.callbacks.length>0){
				setTimeout(()=>{
					that.callbacks.forEach(callbacksObj=>{
						callbacksObj.onResolved(value)
					})
				})
			}
			
		}
		function reject(reason){
			//状态只能改变一次
			if(that.status !== 'pending'){
				return 
			}
			
			
			//将状态改为resolved
			that.status = 'rejected'
			
			//保存value数据
			that.data = reason
			
			//如果有待执行的callback函数,立即异步执行回调函数
			if(that.callbacks.length>0){
				setTimeout(()=>{
					that.callbacks.forEach(callbacksObj=>{
						callbacksObj.onRejected(reason)
					})
				})
			}
		}
		try{
			//执行器抛出异常 直接reject
			//同步执行。
			//传递过来的一个函数 (resolve,reject)=>{}   
			executor(resolve,reject)
		}catch(error){
			reject(error)		
		}
	}
	
	/*
	 	new Promise((resolve,reject)=>{
	 		
	 	}).then(
	 		value=>{},
	 		reasonal=>{}
	 	)
	 * 
	 * */
	//实例对象的then
	//指定成功或者失败的回调方法
	//返回一个新的promise的结果由onResolved 和onRejected执行的结果决定
	Promise.prototype.then = function(onResolved,onRejected){
		
		//向下传递value
		//没有指定onResolved/   则onResolved: value=>value//我们帮天写
		onResolved = typeof onResolved === 'function'?onResolved:value=>value
		
		//指定默认的失败的回调(实现错误/异常串透的关键点)
		//没有指定onRejected/   则onRejectedd: reason=>{throw reason}//我们帮他写
		onRejected = typeof onRejected === 'function'?onRejected:reason=>{throw reason}
		
		
		//可以不保存 this
		
		//因为then这个函数就是通过 promise实例去调用的,每一个实例都有唯一的callbacks
		const that = this //也要保存一下
		
		
		//返回一个新的promise对象
		return new Promise((resolve,reject)=>{
			//可能调用resolve,可能调用reject
			//调用哪个需要 前一个promise的执行结果,他的执行结果在
			function handler(callback){
				try{
					const ret =  callback(that.data)
					if(ret instanceof Promise){
						
							ret.then(resolve,reject);
						
					}else{
						//返回的是 非Promise对象
						//需要改变 返回的promise的状态--为成功
						resolve(ret)
					}
				}catch(e){
					//第一种情况
					reject(e)//修改状态
				} 
			} 
			
			//pending状态,
			//回调函数已经保存
			//某一时刻,修改了状体,直接进行调用回调
			//并且返回已经修改状态的promise
			if(that.status === 'pending'){ 
				that.callbacks.push({
					onResolved:function(value){
						handler(onResolved)
						
					},
					onRejected:function(resonal){
						 
						handler(onRejected)
						
					}
				}) 
			//先修改状态,然后执行回调函数
			}else if(that.status === 'resolved'){
				//异步处理成功回调
				setTimeout(()=>{
					handler(onResolved)
				})
			}else{   
				//异步处理失败回调				
				setTimeout(()=>{
					handler(onRejected)
				})
			}
			
			
			
			
		}) 
	}
	//实例对象的catch
	//指定失败的回调方法
	//返回一个promise
	Promise.prototype.catch = function(onRejected){
		//在then里面 可能会处理 成功,向下执行
		//因为.catch().then()
		return this.then(undefined,onRejected)
	}
	//函数对象的reject 
	//Promise.reject(1)
	//返回一个失败的promise
	Promise.reject = function(resonal){
		
	}
	//函数对象的resolve
	////Promise.reject(2)
	//返回一个成功的promise
	Promise.resolve = function(value){
		//返回一个成功的或者失败的promise
		return new Promise((resolve,reject)=>{
			//value 是promise对象
			if(value instanceof Promise){
				//根据value的结果为 返回promise的结果
				//value 执行的结果  传递给resolve,传递给reject --简写
				//value.then(resolve,reject)
				value.then(value=>{
					resolve(value)//修改状态
				},reason=>{
					reject(reason)//修改状态
				})
				
			}else{
				resolve(value)//修改返回的状态为成功
			}
			
			
			//value 不是promise对象
			
		})
	}
	
	
	Promise.reject = function(reason){
		return new Promise((resolve,reject)=>{
			reject(reason)
		})
	}
	
	
	//返回一个promise,只有当所有promise都成功时才成功,
	//否则就失败了
	Promise.all = function(promises){
		
		const values = new Array(promises.length)//保存所有成功value的数组
		//成功的数量
		let resolveCounte = 0
		
		return new Promise((resolve,reject)=>{
			//遍历每一个promise的结果
			promises.forEach((p,index)=>{
				//取到p的结果
				//改进,进行包装,防止传过来一个   7这类*********************
				Promise.resolve(p).then(
					value=>{
						//p成功了,将成功的值保存到数组中
						values[index] = value
						resolveCounte++
						
						//如果全部成功,将return的promise 改成成功
						if(resolveCounte === values.length){
							resolve(values)
						}
					},
					//只要有一个失败,整个就失败了
					//不会掉两次---不是pending就不进行调用
					//阻止了多次调用
					reasonal=>{
						reject(reasonal)
					}
				)
			})
		})
	}
	//返回一个promise 器结果由第一个promise完成的确定
	Promise.race = function(promises){
		return new Promise((resolve,reject)=>{
			promises.forEach((p,index)=>{
				//取到p的结果
				Promise.resolve(p).then(//*********************改进
					//不会掉两次---不是pending就不进行调用
					value=>{//一旦成功就返回
						resolve(value) 
					},
					//只要有一个失败,整个就失败了
					//不会掉两次---不是pending就不进行调用
					//阻止了多次调用
					reasonal=>{
						reject(reasonal)
					}
				)
			})
		})
	}
	
	//返回一个promise对象,在指定的时间后才确定结果
	Promise.resolveDelay=function(value,time){
		return new Promise((resolve,reject)=>{
			setTimeout(()=>{
					//value 是promise对象
				if(value instanceof Promise){
					//根据value的结果为 返回promise的结果
					//value 执行的结果  传递给resolve,传递给reject --简写
					//value.then(resolve,reject)
					value.then(value=>{
						resolve(value)//修改状态
					},reason=>{
						reject(reason)//修改状态
					})
					
				}else{
					resolve(value)//修改返回的状态为成功
				}	
			},time)
		})
	}
	
	
	//返回一个promise对象,在指定的时间后才确定结果
	Promise.rejectDelay=function(reason,time){
		return new Promise((resolve,reject)=>{
			setTimeout(()=>{
				reject(reason)	
			},time)
		})
	}
	
	//暴露
	window.Promise = Promise
	
})(window)

测试

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<body>
	</body>
	<script type="text/javascript" src="lib/Promise.js" ></script>
	<script type="text/javascript">
		
		const p = Promise.rejectDelay(3,3000)
		p.catch(
			resonal =>{
				console.log(resonal)
			}
		)
		
		const p2 = Promise.resolveDelay(3,3000)
		p2.then(
			value =>{
				console.log(value)
			}
		)
		
		
		
	</script>
</html>

其中Promise.js中的then缩写部分来源

//重要的点。改变返回promise的状态
	
	//实例对象的then
	//指定成功或者失败的回调方法
	//返回一个新的promise的结果由onResolved 和onRejected执行的结果决定
	Promise.prototype.then = function(onResolved,onRejected){
		//可以不保存 this
		//向下传递value
		//没有指定onResolved/   则onResolved: value=>value//我们帮他写
		//return 1    
		onResolved = typeof onResolved === 'function'?onResolved:value=>value
		
		//指定默认的失败的回调(实现错误/异常串透的关键点)
		//没有指定onRejected/   则onRejectedd: reason=>{throw reason}//我们帮他写
		onRejected = typeof onRejected === 'function'?onRejected:reason=>{throw reason}
		
		
		
		////////////////////////////////////////////////////////
		//因为then这个函数就是通过 promise实例去调用的,每一个实例都有唯一的callbacks
		//这次的
		const that = this //也要保存一下
		
		
		//返回一个新的promise对象
		return new Promise((resolve,reject)=>{
 			//可能调用resolve,可能调用reject
			//调用哪个需要 前一个promise的执行结果,他的执行结果在
			
				if(that.status === 'pending'){
					// 状态为pending,先保存回调函数
					//一旦成功就会调用onResolved 这个方法
					//执行完这个方法后,为什么要影响返回promise的状态呢?
					//因为.then 返回的也是Promise对象
					//也就是当前状态还没有被修改,先执行了then,然后才会去改变状态
					//改变状态的时候 立即执行回调函数---在执行器里面异步执行回调
					//保存了回调函数
					that.callbacks.push({
						//从pendding---》成功状态的时候,就会调用这个回调
						onResolved:function(value){//或者that.data
							
							//不需要包裹setTimeOut() 因为在执行器执行的时候
							//已经包裹了一层setTimeout
							//然后执行的结果====》修改返回的状态
							//onResolved(that.data);//或者value
							//拷贝一下代码
							try{
								//回调函数一执行。
						    /*
						     	状态还没改,是通过构造器返回的两个函数修改状体的。
						     	但是我们先 执行了.then(回调1,回调2),将这两个回调放在 数组中
						     	将来某一天,状态修改了,就会执行onResolved方法
						     	也就是执行了.then(onResolved,onRejected) 在构造器里面调用的
						     	调了onResolved方法---》返回了新的promise对象
						     		return new Promise((resolved,rejected)=>{
						     			可能在这里面调用构造器的方法了 修改状态的方法
						     			resolved(value)或者rejecte(reason) //状态改了,值也保存了
						     			//但是此时的回到函数没有哦
						     		})
						     		返回了新的实例----》传一个函数过去
						     		构造器返回两个函数过来===》
						     		所以就通过ret.then(进行push函数)
						     	
						     * */
							const ret =  onResolved(that.data)
							if(ret instanceof Promise){
								//返回的promise 
								//that.then(resolve=>{} return new Promise})
								//这个返回的promise的状态已经被修改了
								//只需要指定,他往哪走
								//**********************************
								//ret  promise实例会进行回调
								//执行下面value---》		代表ret的状态为成功
								//执行下面的resonal---》 代表ret的状态为失败
									/*ret.then(
										value=>{
											resolve(value)//修改状态
										},resonal=>{
											reject(resonal)//修改状态
										}*/ 
									//*********************************************
									//简写由来
									/*
									 	function fn(event){
									 		
									 	}
									 	div.onclick = function(event){
									 		fn(event)
									 	}
									 	/////////////////////////修改
									 	div.onclick = fn  //就可以实现了传递参数的问题了
									 	
									 	
									 	
									 * */
									
									//***************************************

									//回调函数 传递 参数 过去,然后我再调用
									//所以可以简写
									//给返回的promise  进行修改状态
									
									
									//返回的promise执行的结果
									//去判断要返回promise的状态
									
									
									ret.then(resolve,reject);//立即执行。
									/*
									 * 由于当前的处理结果 返回的是一个new Projecte
									 *    不知道他处理的怎么样
									 * 
									 * 但是我能通过  ret.then(成功了走这,失败了走这)
									 * 这个返回的promise执行成功了,我这个返回的promise对象也要成功
									 *  //调用 113行的 构造器给你的两个方法
									 ret.then(
										value=>{
											resolve(value)//修改状态
										},resonal=>{
											reject(resonal)//修改状态
										}
									 * */
								)
							}else{
								//返回的是 非Promise对象
								//需要改变 返回的promise的状态--为成功
								resolve(ret) //  .then{throw e}  直接导致返回的promise失败
								  //构造器给你的两个方法,
							}
						}catch(e){
							//第一种情况
							reject(e)//修改状态  构造器给你的两个方法
						} 
							
						},
						onRejected:function(resonal){
							//然后执行的结果====》修改返回的状态
							//不需要包裹setTimeOut() 因为在执行器执行的时候
							//已经包裹了一层setTimeout
							//onRejected(resonal)
							//拷贝
							try{
							const ret =  onRejected(that.data)
							if(ret instanceof Promise){
								//返回的promise 
								//这个返回的promise的状态已经被修改了
								//只需要指定,他往哪走
								//**********************************
								//ret  promise实例会进行回调
								//执行下面value---》		代表ret的状态为成功
								//执行下面的resonal---》 代表ret的状态为失败
									/*ret.then(
										value=>{
											resolve(value)//修改状态
										},resonal=>{
											reject(resonal)//修改状态
										}*/

									
									
									
									//*********************************************
									//简写由来
									/*
									 	function fn(event){
									 		
									 	}
									 	div.onclick = function(event){
									 		fn(event)
									 	}
									 	/////////////////////////修改
									 	div.onclick = fn  //就可以实现了传递参数的问题了
									 	
									 	
									 	
									 * */
									
									//***************************************

									//回调函数 传递 参数 过去,然后我再调用
									//所以可以简写
									ret.then(resolve,reject);
								)
							}else{
								//返回的是 非Promise对象
								//需要改变 返回的promise的状态--为成功
								resolve(ret)
							}
						}catch(e){
							//第一种情况
							reject(e)
						}
							
						}
					})
				//以下需要返回新的promise
				//新的promise 由onResolved/onRejected 返回的结果决定
				}else if(that.status === 'resolved'){
					//状态已经改了,必然会存放value
					//that.data = value // resolved函数
					/*
					 *1.如果在onResolved执行的过程中,抛出异常,所以将要返回的promise失败
					 * 		.then(
					 	* 		value=>{
					 	* 			throw 3
					 	* 		}
					 * 2.如果onResolved执行的结果不是promise对象
					 * 		.then(
					 	* 		value=>{
					 	* 			return 1
					 	* 		}
					 *        则新的promise,需要执行成功,
					 * 3.如果onResolved执行的结果是promise,就会根据这个promise的结果去执行 成功或者失败
					 *      
					 * 		 .then(
					 * 			value=>{
						 *          return new Promise((resolve,reject)=>{
						 * 					//resolve()//改变为成功,status 为 resolve
						 * 					//reject()//改变为失败     status  为rejected
						 * 			})
					 * 		
					 * 			}
					 * 		  )
					 *       //根据执行的结果的promise对象进行 执行新的promise
					 */
					setTimeout(()=>{
						try{
							const ret =  onResolved(that.data)
							if(ret instanceof Promise){
								//返回的promise 
								//这个返回的promise的状态已经被修改了
								//只需要指定,他往哪走
								//**********************************
								//ret  promise实例会进行回调
								//执行下面value---》		代表ret的状态为成功
								//执行下面的resonal---》 代表ret的状态为失败
									/*ret.then(
										value=>{
											resolve(value)//修改状态
										},resonal=>{
											reject(resonal)//修改状态
										}*/

									
									
									
									//*********************************************
									//简写由来
									/*
									 	function fn(event){
									 		
									 	}
									 	div.onclick = function(event){
									 		fn(event)
									 	}
									 	/////////////////////////修改
									 	div.onclick = fn  //就可以实现了传递参数的问题了
									 	
									 	
									 	
									 * */
									
									//***************************************

									//回调函数 传递 参数 过去,然后我再调用
									//所以可以简写
									//返回的promise需要改变哪个状态,得根据 返回的promise的状态去执行
									ret.then(resolve,reject);
								)
							}else{
								//返回的是 非Promise对象
								//需要改变 返回的promise的状态--为成功
								resolve(ret)
							}
						}catch(e){
							//第一种情况
							reject(e)
						}
					})
				}else{ //和成功的代码一致,只是修改了  onResolve------》onRejected
					//rejected 
						//onRejected(that.data) 
					setTimeout(()=>{
						try{
							const ret =  onRejected(that.data)
							if(ret instanceof Promise){
								//返回的promise 
								//这个返回的promise的状态已经被修改了
								//只需要指定,他往哪走
								//**********************************
								//ret  promise实例会进行回调
								//执行下面value---》		代表ret的状态为成功
								//执行下面的resonal---》 代表ret的状态为失败
									/*ret.then(
										value=>{
											resolve(value)//修改状态
										},resonal=>{
											reject(resonal)//修改状态
										}*/

									
									
									
									//*********************************************
									//简写由来
									/*
									 	function fn(event){
									 		
									 	}
									 	div.onclick = function(event){
									 		fn(event)
									 	}
									 	/////////////////////////修改
									 	div.onclick = fn  //就可以实现了传递参数的问题了
									 	
									 	
									 	
									 * */
									
									//***************************************

									//回调函数 传递 参数 过去,然后我再调用
									//所以可以简写
									//修改转台   由ret执行的结果来确定 是成功还是失败的专题
									ret.then(resolve,reject);
								)
							}else{
								//返回的是 非Promise对象
								//需要改变 返回的promise的状态--为成功
								//修改状态
								resolve(ret)
							}
						}catch(e){
							//第一种情况
							reject(e)
						}
					})
					
				}
			
			
			
			
		})
		
		
		
	}

async await 说明

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<body>
	</body>
	<script type="text/javascript">
		/*
		 *	async function 
		 *   用来定义一个返回asyncFunction对象的异步函数
		 * 
		 * async  函数         :async右边是函数
		 *    函数的返回的promise的结果由函数执行的结果决定
		 * 	
		 * await 表达式       : await 右边是表达式
		 * 
		 * 
		 * 
		 */
		
		/*function fn1(){
			return 1
		}
		const a = fn1()//结果为1*/
		
		//加上async后
		/*
		async function fn1(){
			return 1       //会进行封装,返回一个新的promise对象
		}
		const ret = fn1()
		console.log(ret)//Promise对象*/
		
		
		//async 返回值 为promise对象
		//失败的promise对象
		async function fn1(){
			throw 3        //会进行封装,返回一个新的promise对象
		}
		const ret = fn1()//失败的promise对象
		ret.then(
			value=>{
				console.log(value,'成功')
			},
			resonal=>{
				console.log(resonal,'失败')
			}
		)
		//失败的promise
		async function fn2(){
			return Promise.reject(3232)
		}
		const k = fn2()//失败的promise对象
		k.then(
			value=>{
				console.log(value,'成功')
			},
			resonal=>{
				console.log(resonal,'失败')
			}
		)
		
		//延迟 失败。。。。。
		async function fn3(){
			return new Promise((resovle,reject)=>{
					setTimeout(()=>{
						reject(3232)
					},3000)
				})
		}
		const k3 = fn3()//失败的promise对象
		k3.then(
			value=>{
				console.log(value,'成功')
			},
			resonal=>{
				console.log(resonal,'失败')
			}
		)
		
		
		/////////////////////////////////////////////
		 function fn6(){
			return Promise.resolve(3113313)
		}
		
		//await 必须在函数里面使用
		//函数里面使用了await ,则函数前面必须声明async
		// 通过async 声明的函数,将会 返回一个包装过的promise对象
		// await 表达式
		// await 函数-返回一个promise(可以自己放回,也可以使用async进行声明这个函数,则会返回包装好的promise 处理的结果)
		//			不加await,则会接收promise对象
		// await 普通函数====》结果就是这个普通函数
		// await 普通函数()===》普通函数处理的结果
		async function fn7(){
			//const value = fn6()//不想.then 获取到promise处理的结果
			//添加 await 就可以获得 promise处理的结果
			const value = await fn6()  //这个await 右边为promise
									   //这个结果就是promise处理之后的值
			//等待 fn6执行的结果
			//函数内部使用了await
			//则函数必须声明为async
			console.log(value)			//await右边不是promise,得到的表达式就是这个值本身
			
			
			const k2 = await 888
			console.log(k2)
			
			
			const k3 = await function(){
				console.log('hello')
			}
			console.log(k3)//函数本身
										
			
			
			const k5= await (function(){
				console.log('hello')
			})()
			console.log(k5)//函数本身
			
		}
		fn7()
		
		
		//await 等待一个失败的promise
		function km(){
			//return 34334343443443
			return new Promise((resolve,reject)=>{
				reject('失败咯失败咯')
			})
		}
		
			
		(async function (){
			try{
				const mm = await km() //异常直接 走catch,e就是reject传入的值
									  //await 失败的表达式(函数执行,不返回promise)===》也会走catch
				//const mm = await km
				console.log(mm+'mm')
			}catch(e){
				console.log(e)  //
			}
		})()
		
		
		
		
		
		
		
	</script>
</html>
发布了33 篇原创文章 · 获赞 0 · 访问量 469
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览