場景:讀取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循環有多快呢,可以自己測試下