2012-05-30 27 views
1

我覺得自己很愚蠢,因爲問一些很瑣碎的事情,但我真的想要最好的實踐答案(除非沒有其他可行的方法,否則我不會尋找「setTimeout」解決方案 - 儘管我懷疑是這樣)。Javascript回調時間

快速瀏覽:我有一個數組,我想從回調中推送到。在我填充數組之後,我想在回調之外使用它。

實際應用:我有一個城市陣列,我想用Google的API對它們進行地理編碼,並用所有LatLng的數組填充一個數組。之後,我將使用它們創建標記對象,將它們添加到聚類器中,無論如何。

coder = new google.maps.Geocoder(); 
$places = ['Truro, NS', 'Halifax, NS', 'Sydney, NS', 'Dartmouth, NS']; 
all_the_pins = Array(); 
for(i in $places){ 
    var $place = $places[i]; 
    coder.geocode({address:$place}, function(res, stat){ 
     switch(stat){ 
      case 'OK': 
       all_the_pins.push(res[0].geometry.location); 
       break; 
     } 
    }); 
} 
console.log(all_the_pins); 

編輯:澄清問題: 問題是不是範圍問題all_the_pins變量或是否是全球性與否,如果你是在回調中檢查all_the_pins你會看到它是相同的變量(被推送到)。問題在於,因爲推送發生在回調內,所以在下面運行console.log之前它們不會發生。

+0

什麼問題?你的位置將積聚在'all_the_pins'數組中。如果您全局聲明該數組,它將在全局範圍內可用。 – jfriend00

+0

只需將您的數組聲明爲全局變量? 'var all_the_pins = [];'在文檔的頂部。它可以在所有範圍內訪問。 –

+0

我同意,我不明白這個問題...... – Jonathan

回答

0

您的其他代碼是否可以存在於另一個回調中?我會設置一個函數,它只會在被調用x次(即輸入數組的長度)之後執行。

coder = new google.maps.Geocoder(); 
$places = ['Truro, NS', 'Halifax, NS', 'Sydney, NS', 'Dartmouth, NS']; 
all_the_pins = Array(); 

function myCallback(count, totalCount, all_the_pins) { 
    if (count != totalCount) return; 

    console.log(all_the_pins); 
} 

count = 1; 

for(i in $places){ 
    var $place = $places[i]; 
    coder.geocode({address:$place}, function(res, stat){ 
     switch(stat){ 
      case 'OK': 
       all_the_pins.push(res[0].geometry.location); 

       myCallback(count, $places.length, all_the_pins); 
       count++; 
       break; 
     } 
    }); 
} 
+0

不要在數組中使用for-in-loop。 – Bergi

+0

我知道,我只是複製了他的其他代碼 - 答案是關於設置回調 – freejosh

1

因爲你的問題不明確,我會大膽地說,你要處理的all_the_pins array當你所有的地理編碼調用做了猜測。由於地理編碼函數調用是異步的,因此必須跟蹤所有地理編碼調用何時完成,然後才能使用最終數組。

如果是這樣,你可以是這樣做的:

var coder = new google.maps.Geocoder(); 
var $places = ['Truro, NS', 'Halifax, NS', 'Sydney, NS', 'Dartmouth, NS']; 
var all_the_pins = Array(); 
var remaining = $places.length; 
for (var i = 0, len = $places.length; i < len; i++) 
    var $place = $places[i]; 
    coder.geocode({address:$place}, function(res, stat){ 
     switch(stat){ 
      case 'OK': 
       all_the_pins.push(res[0].geometry.location); 
       break; 
     } 
     --remaining; 
     if (remaining == 0) { 
      // all_the_pins data is set here 
      // call a function and pass the array to it or put your 
      // code here to process it 
      console.log(all_the_pins); 
     } 
    }); 
} 

注:我也更改爲正確的類型for循環用於重複的數組。 for (var i in xxx)用於迭代對象的屬性,而不是數組的元素。

1

不,setTimeout在這裏絕對沒用。如果您有多個異步請求,並且想在所有請求都回撥時執行某些操作,則唯一的可能是計數器。在最後一次回調之後,打開的請求數量將降至空值;然後執行你想要的。

var coder = new google.maps.Geocoder(); 
var places = ['Truro, NS', 'Halifax, NS', 'Sydney, NS', 'Dartmouth, NS']; 
var all_the_pins = []; 
for (var i=0; i<places.length) 
    coder.geocode({address:places[i]}, function(res, stat){ 
     if (stat == 'OK') 
      all_the_pins.push(res[0].geometry.location); 
     else 
      all_the_pins.push(stat); 

     // counter is length of results array: 
     if (all_the_pins.length >= places.length) { 
      console.log(all_the_pins); 
     } 
    });