天天看点

异步处理的终极方案:async,await

进入个人博客 Eighteen Blog

异步函数我们经常会用到,最为常见的就是ajax,利用ajax请求我们的服务端获取数据,然后执行回调函数。

一,普通的ajax

ajax(url,(res)=>{
	console.log(res);
	})
           

最普通的异步请求函数,那么当我们有两个异步请求,且请求B需要依赖请求A的时候,该怎么处理?

//ajaxA
ajax(url1, (resA) => {

	ajax(url2, (resB) => {
		
		console.log(resA);
		console.log(resB);
		// ajax(url3, ()=>{} ...  类似这样有多少个依赖关系就一直嵌套,形成回调地狱(函数多层嵌套)。
	
	})

})
           

这样处理我们的多层异步依赖,会最终形成金字塔的形状,层层嵌套,看不清代码逻辑,难以维护且难以追踪。

二,使用promise处理异步回调,使其变成链式调用。

new Promise((resolve, reject) => {

	  ajax(url, (res)=>{
	 		resolve(res)//完成状态   promise的状态只可定义一次,下一行的reject将不起作用。
	 		reject('reject')//拒绝状态
		})

})

.then(res => {

		return new Promise((resolve, reject) => {
	  	//如果第二个为异步函数,继续return 一个promise,resolve的参数即是下个回调的参数。
		
			ajax(url, (res) => {
		 		resolve(res);
			})
			
		})
		
})

.then(res => {
	return '非异步';//return 的值是下一个then中的参数。
})

.then(res => {
	console.log(res); // "非异步"
})
           

至此,我们的代码看起来清晰了不少,当然我们可以遵守尽量给函数语义命名的规则,进一步的简化代码。

// 变量声明函数

let promise1 = new Promise((resolve, reject) => {

 	ajax(url, (res)=>{
 		resolve(res)//完成状态   promise的状态只可定义一次,下一行的reject将不起作用。
 		reject('reject')//拒绝状态
	})

})

let promise2 = new Promise((resolve, reject) => {  
	//如果第二个依然为异步函数,继续return 一个new promise,resolve的参数即是下个回调的参数。
	
	ajax(url, (res)=>{
 		resolve(res)
	})
	
})

promise1()

.then(promise2)

.then(res => {
	return '非异步';//return 的值是下一个then中的参数。
})

.then(res => {
	console.log(res); // "非异步"
})
           

这样代码更加的简介清晰。

三,我们可以使用async和await解决回调问题。

function takeLongTime() {
    
    return new Promise((resolve, reject) => {
        setTimeout(() => resolve(10), 1000);
    });
    
}

function takeLongTime2(v) {
    
    console.log(v); // 10
    
    return new Promise(resolve => {
        setTimeout(() => resolve(v + 20), 10);
    });

}

async function test() {
    const v = await takeLongTime(); //10
    const b = await takeLongTime2(v);  //30
    console.log(b);
}

test();
           

await 我们从名字可以看出来意思是等待异步的意思,即它可以让异步回调变得像同步函数,并且会阻塞下一步,但是!这一切都是发生在async中的,而async是异步的,所以整个js并不会被阻塞。所以await要写在async中。当然单纯的await和async是并不能解决问题。可以看到还是需要promise的。

async和await内部实现了Generator ,然后结合promise,是他们的语法糖,大家可以自行了解一下。(它可以使函数内部分步执行)

继续阅读