最近在 JS 中使用 AJAX 遇到了一个坑,大致流程是,我需要循环的调用某一个方法,在该方法中需要使用 AJAX 去获取数据;但是我在主方法中却没有得到我想要的数据。
代码如下:
//构建表格数据
var buildOrderTtable = function(res){
//在绑定数据前先清除之前的数据。
$("#order_table tbody").empty();
//在这里我需要循环的调用 getBus 方法,去获取数据,后面需要使用。
$.each(res.data.pageInfo.list,function(index,item){
getBus(item.busId);
var timeIdTd = $("<td></td>").append(formatDate(item.ordTime));
var priceIdTd = $("<td></td>").append("¥"+item.price);
.....
});
}
getBus 方法:
var getBus = function(bId){
$.ajax({
type:"GET",
url:"${APP_PATH}/getBusinessById",
data:{"id":bId},
success:function(res){
//console.log(res);
busName = res.data.bus.storeName;
busTel = res.data.bus.phone;
}
});
}
但是每次调用 getBus 方法时,请求完后不会立即调用回调函数,导致不能在主函数中及时获取到相应的数据。
1、概念
AJAX 的全称是 AsynchronousJavaScript and XML,其中,Asynchronous 是异步的意思,中文意思为异步的 JavaScript 和 XML。
2、同步和异步的区别
首先,js是一个单线程的执行环境,即一次只能执行一个任务。如果有数个任务,那么这些任务会从上至下依次挨个执行。这种执行方式的好处是简单,实现也简单,缺点是这个如果有大量的任务,或者其中一个任务耗时时间很长,其他的任务暂时无法执行,就会造成浏览器无响应(俗称假死,卡死)。
针对这种情况,js出现了同步和异步的概念。“同步模式”就是上一段的模式,后一个任务等待前一个任务结束,然后再执行,程序的执行顺序与任务的排列顺序是一致的、同步的;“异步模式”则完全不同,每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执行,所以程序的执行顺序与任务的排列顺序是不一致的、异步的。
到这儿就能明白我上面的问题所在,由于 AJAX 是异步的,当我循环地调用 getBus 方法时每一次调用都是一次新的任务,在当前任务还未执行完,即未执行回调函数时就开始了下一个任务,导致未能及时获取当前任务传输的数据,
3、async 关键字
AJAX中根据 async 的值不同分为同步(async = false)和异步(async = true)两种执行方式;这个async这个属性,用于控制请求数据的方式,默认是true,即默认以异步的方式请求数据。
- 当 async值为 false (同步)时: 顺序处理,当执行当前AJAX的时候会停止执行后面的JS代码,直到AJAX执行完毕后时,才能继续执行后面的JS代码。
- 当 async值为 true (异步)时: 并行处理,当我们向服务器发出一个请求时,在服务器没返回结果之前,我们还是可以执行其他操作。
所以我上面的代码只需加上 async=flase 就可以解决问题。
var getBus = function(bId){
$.ajax({
type:"GET",
url:"${APP_PATH}/getBusinessById",
data:{"id":bId},
async:false,
success:function(res){
//console.log(res);
busName = res.data.bus.storeName;
busTel = res.data.bus.phone;
}
});
}