Promise

一、Promise

问题描述:

        起因是因为获取页面信息的时候需要等待一些时间,因为是异步操作,所以这段时间里可能其他地方要用到页面数据,换句话说,就是你想要执行有前后关系的异步操作。

APP 中接收数据代码:

	//页面数据
	var pageDatas=0
	//异步获取数据
	var getPageDatas=()=>{
		//假设异步函数需要花费一些1s
		setTimeout(()=>{//此处模仿异步函数操作
			pageDatas=1
		},1000)
	}
	getPageDatas()
	console.log(pageDatas)//答案肯定会输出0,因为我试了~~
/*
	因为getPageDatas函数里有异步函数,
	在异步函数中处理了我们需要的pageDatas,浏览器还没等异步函数处理完就开始输出pageDatas,自然拿不到
*/	


原因分析:

        异步函数执行时,那同步函数或其他异步函数执行的时候如果想用此异步操作处理的结果,那就想法把异步变同步呗,如果能监听到此异步操作何时能完成,到那时我们再执行同步操作或是异步函数即可。简单的说就是异步函数执行的太慢了,耽误我拿值了。


解决方案:

        解决的办法有很多,第一种直接把后面这种操作写到异步操作里,虽然简单直接,但是显得异步操作很长,过长就影响二次阅读;第二种(也是分情况的哈),如果用vue的话,可以对页面数据进行watch监听,当监听到页面数据发生改变的时候就可以进行相关操作;第三种也比较有局限性了,就是如果异步操作是ajax请求的话,他里面有个参数async,默认是true,意思就是请求设置成异步请求,我们给他设置成false,必须等待请求结束后才能执行下一步操作;第四种如果没有用vue的话,需要用到promise函数,这里说第三种。
        Promise教程有很多,网上太多啦,自己尝试去吧。简单说一下刚刚那个例子用promise如何解决。

	//页面数据
	var pageDatas=0
	//异步获取数据
	var getPageDatas=()=>{
		return new Promise((resolve,reject)=>{
			//假设异步函数需要花费一些1s
			setTimeout(()=>{//此处模仿异步函数操作
				pageDatas=1
				resolve(pageDatas)//用于输出成功的操作
			},1000)
		})
	}
	getPageDatas().then(res=>console.log(res))//res就是resolve传过来的数据
	//此时输出的就是1

        唯一不方便的就是需要自己判断什么时候会抛出异常,毕竟有then在就有catch的身影。

Promises链式回调

        链式回调也是解决异步操作的先后顺序问题。

function a(){
	return new Promise((resolve,reject)=>{
		setTimeout(()=>{
			console.log(1)
			resolve(1)
		},1000)
	})
}
			
			
function b(){
	return new Promise((resolve,reject)=>{
		setTimeout(()=>{
			console.log(2)
			resolve(2)
		},1000)
	})
}
			
			
function c(){
	return new Promise((resolve,reject)=>{
		setTimeout(()=>{
			console.log(3)
			resolve(3)
		},1000)
	})
}
				
a().then(res=>{
	return b()
}).then(res=>{
	return c()
}).then(res=>{
	console.log(res)
}).catch(err=>{
	console.log(err)
})



async函数

        接上面例子,还是三个promise函数,这个函数的主要作用是更便捷的使用promise函数,举个栗子,假如你想要获取a执行后的函数结果,那么你只能这样做

	a().then(res=>{
		console.log(res)
	})

上面这样做确实有点麻烦,然而,async却能轻轻松松拿到,并且同样是按顺序执行完a函数才能执行b函数,以此类推。
await关键字,大概意思就是,在这里等一下我后面罩着的函数执行完成,后面的函数先等等,等着函数执行完了再执行下一个。

引用官方的话来讲:
async函数的函数体可以被看作是由0个或者多个await表达式分割开来的。从第一行代码直到(并包括)第一个await表达式(如果有的话)都是同步运行的。这样的话,一个不含await表达式的async函数是会同步运行的。然而,如果函数体内有一个await表达式,async函数就一定会异步执行。

        意思大概是说,async函数可以是同步函数,条件是没有一个await表达式,否则就是异步函数

	
	async function init(){
		var text1,text2,text3
		try{
			text1=await a()
			text2=await b()
			text3=await c()
			console.log(text1,text2,text3)
		}catch(err){
			console.log(err)
		}
	}

        当然如果中间某个函数出现错误,那么catch自然会抛出,并且不会继续往下执行。但凡有错,绝不往下进行。

构建回调函数

        饶有兴趣自习了一下回调函数,其实说白了就是一个函数本身昨晚了一些事儿之后呢就告诉调用者我做完了。接着上面的例子

var data=1

var init=async (callback)=>{
	var text1,text2,text3
	try{
		text1=await a()
		text2=await b()
		text3=await c()
	}catch(e){
		console.log(e)
	}finally{
		return callback && callback([text1,text2,text3])
	}
}

init(v=>{
	console.log(v)//[1,2,3]
})

# 回调函数需要在合适的时机执行,判断callback是否存在且是否是函数是有必要的
# 注意this指向问题
var init2=async (callback)=>{
	var text1,text2,text3
	try{
		text1=await a()
		text2=await b()
		text3=await c()
	}catch(e){
		console.log(e)
	}
	
	if(callback & typeof callback ==='function'){
		callback([text1,text2,text3])
	}
}
init2(v=>{
	console.log(v)//[1,2,3]
})

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值