2012-07-01 151 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