作为一名web开发人员,基本都会使用Ajax向后台请求或发送数据。常常会碰到这样一种业务场景,某些数据处理操作会在几项请求后操作,而一般情况下不允许使用同步ajax请求(阻塞页面进程,可能会造成前端页面处于假死状态),如何实现?
业务背景,有三个请求分别地址分别为url1,url2,url3,现要求:请求url1返回数据后,进行url2请求,url2返回数据后进行url3请求。
实现:
1、ajax回调函数
ajax函数定义如下(利用jquery $.ajax):
//两个参数,url是请求连接,callback是回调函数
function ajax(url,callback){
$.ajax({
url:url,
async:true,
success:(res)=>{
if(callback){
callback(res);
}
},
error:(err)=>{
console.error(err);
}
})
}
则使用回调解决请求顺序问题的方式如下:
ajax('data1.txt',(res1)=>{
console.log(res1);
ajax('data2.txt',(res2)=>{
console.log(res2);
ajax('data3.txt',(res3)=>{
console.log(res3);
})
})
});
输出:data1
data2
data3
这种方法虽然能实现顺序请求,但当有很多个请求时,会嵌套很多层回调,不利于代码维护。
2、利用promise实现
定义一个返回promise的函数
function promise(url) {
return new Promise((resolve,reject)=>{
ajax(url,(res)=>{
resolve(res);
})
})
}
如下即可进行数据的顺序请求,
promise('data1.txt').then((res1)=>{
console.log(res1);
promise('data2.txt').then((res2)=>{
console.log(res2);
promise('data3.txt').then((res3)=>{
console.log(res3);
})
})
})
在Promise的then可以对返回数据进行处理,此种方法与第一种方法好像并没有很大区别。Promise有个好处在于,当需要某个数据处理操作依赖多个请求返回数据时,使用Promise.all([])方法非常简单。
假设某个数据操作依赖url1,url2,url3都完成时,才进行,可实现如下:
Promise.all([promise('data1.txt'),promise('data2.txt'),promise('data2.txt')]).then(([res1,res2,res3])=>{
console.log(res1,res2,res3);
}),
all的参数是一个promise数组,当三个请求都完成时,在then中可对参数进行处理,then的参数也是一个数组。
3、asyns await实现顺序请求。
实现如下:
async function showData(){
let data1 = await promise('data1.txt');
console.log(data1);
let data2 = await promise('data2.txt');
console.log(data2);
let data3 = await promise('data3.txt');
console.log(data3);
}
这种写法易读性很好,避免了多层回调函数嵌套。
注:1、如有错误,请大家指正。写作过程中有参考网上其他人文章,如有侵权,请连续我删除。
2、promise是ES6中的语法,async和await是ES7中语法,如果要代码要兼容早期版本浏览器,可使用babel对代码进行编译。