2012-07-01 141 views
0

我是Javascript編程的新手,已在許多地方查找過此信息,但尚未找到一個工作解決方案,因此我在此處發佈此問題。使用從Javascript中的回調函數返回

在for循環我試圖請求的區域的POI(所述路線的腿) -

service.search(request, callback); 

其中請求包括如位置和查詢類型POI的參數。我已經實現如下的回調函數 -

function callback(myResults, status) { 
    if (status == google.maps.places.PlacesServiceStatus.OK) { 
     alert('myResults: ' + myResults.length); 
     // entire remaining code here, where I do some processing on the POIs. 
    } 
} 

此代碼工作,並在該路線的每腿我能看到興趣點,並使用警報還顯示數量的POI。

我的問題是,我不想在這裏爲每條腿處理「myResult」,但是收集整條路線的所有結果(由多條腿組成),然後立即執行處理。

  1. 我首先想到創建一個全局變量(「myPOIs」),並在每條腿追加「myResults」,一旦整條路線進行解析,然後處理此myPOIs,但我不能(或我不知道如何)將這個myResults追加到一個全局變量myPOIs。

  2. 另一種選擇,我想到的是從回調函數中獲取返回值(myResults),然後收集(附加)所有結果。

1和2之間的唯一區別是,在如圖1所示,其一個全局變量我將追加myResults到if條件內,並且在圖2,如果if條件爲真,那麼myResults返回service.search然後在那裏收集結果。

我嘗試使用myPOIs.push(myResults)和其他一些選項,但是當我檢查myPOIs.length時,它始終爲空。我真的不知道如何從回調函數中獲取myResults。

任何建議/ throughts/help對我來說都是非常有用的。

而我只想使用javascript而沒有其他任何東西。

非常感謝提前, AXS

+0

你還可以加入for循環代碼嗎? –

回答

2

假設您呼叫的搜索是這樣的:

for (var i = 0; i < legs.length; i++) { 
    service.search(legs[i], callback); 
} 

,那麼你可以通過保持所有的結果軌道做到這一點,你已經叫回來的次數:

var callbacksOutstanding = legs.length; 
var allPlaces = []; 
var callback = function(legPlaces, status) { 
    if (status == google.maps.places.PlacesServiceStatus.OK) { 
     allPlaces.push.apply(allPlaces, legPlaces); 
    } 
    if (--callbacksOustanding === 0) { 
     processPlaces(allPlaces); 
    } 
}; 
for (var i = 0; i < legs.length; i++) { 
    service.search(legs[i], callback); 
} 

其中processPlaces是您編寫的用於處理整個PlaceResult對象數組的一些函數。

現在三個var語句有沒有全局變量,如果這是所有包裹在一個函數(因爲它應該是),因爲在Javascript中,你可以和應該定義等功能內部的功能。如果你這樣做,內部函數將有權訪問外部函數中的變量。所以對我來說,這可能是這樣的:

function findAndProcessPlaces(legs) { 
    var callbacksOutstanding = legs.length; 
    var allPlaces = []; 
    var callback = function(legPlaces, status) { 
     if (status == google.maps.places.PlacesServiceStatus.OK) { 
      allPlaces.push.apply(allPlaces, legPlaces); 
     } 
     if (--callbacksOustanding === 0) { 
      processPlaces(allPlaces); 
     } 
    }; 
    for (var i = 0; i < legs.length; i++) { 
     service.search(legs[i], callback); 
    } 
} 

注:該allPlaces.push.apply行執行一個陣列的就地拼接到另一個。你也可以這樣寫:

allPlaces = allPlaces.concat(legPlaces) 

在這一點上。

+0

謝謝,這種方法工作並解決了我的問題。由於回調是異步的,並不一定遵循順序進程,因此必須跟蹤回調的數量並等待所有回調完成。你的var回調優秀是一個非常好的建議,我想這是解決這個問題的關鍵。另外第二重要的是allPlaces.push(legPlaces)不起作用。我不知道爲什麼,但你必須使用allPlaces.push.apply(allPlaces,legPlaces);以追加到解決這個問題也非常關鍵的數組中。我沒有嘗試concat方法。 – axs

+0

快速註釋 - 在創建的最終函數中,變量var allPlaces = [];應該在函數findAndProcessPlaces之外,因爲我希望所有腿的所有結果都必須存儲在allPlaces中。 – axs

0

做一個全局變量:

var POIResults = []; 

在你的回調函數

POIResults.push(myResults); 

後來在您方便的調用它迭代的一個功能陣列

function checkResults(){ 
for(var i = 0; i < POIResults.length; i++){ 
    //TODO: check POIResults[i] 
} 
} 
+0

謝謝,但曾試過這種方法。事實上,這是我在我的問題陳述中提到的第一件事。正如我現在從lan接受的答案中發現的那樣,這種方法不起作用,因爲回調是異步的,你永遠不知道什麼時候所有結果都被推送到POIResults上。也由於某種原因,只是POIResults.push(myResults);不起作用,它必須是POIResults.push.apply(POIResults,myResults);正如在 – axs

+0

@axs之後的回答中所建議的 - 正如Ian回答中所討論的那樣,我假設你創建了一個外部全局數組,但不是一個真正的全局數組。在給定正確條件的情況下,異步推入數組的工作 - 主要是數組是一個真正的全局變量。 –

+0

謝謝特拉維斯。正如你注意到的,我創建了一個外部全局數組,但是如何創建一個真正的全局數組? – axs

0

一個數組定義在回調的邊界內,並在右邊的範圍內應該做的伎倆。你能用全局數組方法發佈代碼嗎?

+0

謝謝,但是單獨在外面定義的這個全局數組並不能完成回調函數。看看lan的答案,下面解決了這個問題。在他創建的最終功能中,只需刪除var allPlaces = [];並把它放在外面,它使變量全局並保存所有結果。 – axs