异步请求遇上for循环,代码怎么设计
场景:读取Excel数据(地名),发送请求到百度地图,从返回的json格式数据取出坐标数据(逗号隔开的两个float型数值),拼接成了分号隔开的一个字符串data,接下来需要利用“百度坐标转换API”,将这些坐标值循环发送过去来转换,
现在遇到的问题是:
1、这个请求是异步的,意味着,后面的请求并不会等他前面的请求返回结果才行动,这就好比,火车站排队购票,大家都抢,后面的人不等他前面的人拿到票就把他挤走了,结果是什么呢,好了,你被挤走了,售票美女给你打印票的速度太慢了,递出的票被后面的人拿到了。真实情况是什么样的呢?如果数据只有几千条,基本上for循环已经结束了,数据还没有拿回来,于是我还没拿到票,我后面第10个人甚至第100个人刚好挤到窗口伸手拿票,结果就是返回的数据跟请求根本对不上号,全部错乱了。
解决方法:首先定义一些全局的变量
var pointsArr = []; //(全局的都用红的),data转换成的数组
var len = 0; //pointsArr 的长度
var num = 0; //每发送一次num+1
var datalist = "" ; //请求回来的数据丢进这个里面
用data2Array方法得到pointsArr 忽略过程
data2Array: function(data){
var dataArr = data.split(";");
var dataArrlen = dataArr.length;
for(var i=0;i<dataArrlen;i++){
pointsArr[i] = new BMap.Point(dataArr[i].split(",")[0],dataArr[i].split(",")[1]);//这是你要循环发送的数据
}
len = pointsArr.length;
bdswich();//开始调用百度api的方法
}
//转换
bdswich: function(){
bdswich: function(){
var convertor = new BMap.Convertor();
convertor.translate([pointsArr[num]], 1, 5, translateCallback);//百度转换方法, translateCallback是回调函数,自动调用
num++;//每发送一次num+1,和for循环类似
}
//回调函数
translateCallback:function (result){
var lng = 0;
var lat = 0;
if(result.status === 0){
lng = result.points[0].lng;
lat = result.points[0].lat;
}
datalist=datalist+"{"+'"lng":'+lng+','+'"lat":'+lat+"},";
setTimeout(control(), 1000); //上面的忽略,这个是关键,定时器,1秒后执行control()函数
}
//控制函数
control: function(){
if(num<len){
bdswich();//只要num没到len,回到开头,循环执行转换函数
}else{
dosomething!!!!!//num自增到len,循环结束
}
}
下面简要的说几个要点:
这个方法的核心是,用数组+定时器代替for循环
首先num=0,发送第一个数据 pointsArr[0],执行完后一定记得num++,
然后在回调函数translateCallback中,定时1秒后执行控制函数control(),即
下面简要的说几个要点:
这个方法的核心是,用数组+定时器代替for循环
首先num=0,发送第一个数据 pointsArr[0],执行完后一定记得num++,
然后在回调函数translateCallback中,定时1秒后执行控制函数control(),即
setTimeout(control(), 1000);
在control()中,判断num和len,没取完值,返回去继续执行转换函数bdswich()
下一轮请求发送继续开始
一般情况下,1000毫秒足够一次请求返回了,但是呢,for循环有多快呢,可以自己测试下
在control()中,判断num和len,没取完值,返回去继续执行转换函数bdswich()
下一轮请求发送继续开始
一般情况下,1000毫秒足够一次请求返回了,但是呢,for循环有多快呢,可以自己测试下