播种 JavaScript 回调函数

3
我有一个谷歌地图,上面有大约200个标记。使用谷歌距离矩阵服务,我可以找到从地址到地图上所有标记的驾车距离。由于API限制,我每次只能提交25个目的地,因此我必须将操作分成8个单独的调用到距离矩阵服务。
我的问题是,由于这些调用是异步的,它们可以以任何顺序返回,因此我对如何最好地将返回的结果与原始标记数组匹配感到困惑。理想情况下,我希望传递一个偏移量给回调函数,以便它确切地知道原始标记数组中的哪25个元素对应于从API调用返回的25个结果,但我不知道如何实现这一点,因此非常感谢任何帮助。
var limit = 25;
var numMarkers = markers.length; // markers is an array of markers defined elsewhere
var numCallbacks = Math.ceil(numMarkers/limit);
var callbackCount = 0;

for(var i = 0; i < numMarkers; i += limit) {
    var destinations = [];

    // Get destination position in batches of 25 (API limit)
    for(var j = i; j < i + limit && j < numMarkers; j++) {
        destinations[j - i] = markers[j].getPosition();
    }

    // Calculate distances
    distMatrix.getDistanceMatrix(
    {
        origins: origin, // array containing single lat/lng
        destinations: destinations,
        travelMode: google.maps.TravelMode.DRIVING,
        unitSystem: google.maps.UnitSystem.IMPERIAL,
        avoidHighways: false,
        avoidTolls: false

    }, function(response, status) {

        if (status == google.maps.DistanceMatrixStatus.OK) {
            var distances = response.rows[0].elements;

            // This is where it would be nice to know the offset in the markers array 
            // that these 25 results correspond to so I can then just iterate through 
            // the distances array and add the data to the correct marker.
        }

        if(++callbackCount == numCallbacks) {
            // All callbacks complete do something else...
        }
    });
}

所以如果有一种方法能够在调用API时,将回调函数的值与for循环中的“i”值匹配起来,那么匹配就会变得容易。但我不是那么擅长JavaScript,所以我不知道如何做到这一点,或者它是否可能。

感谢你们所提供的任何帮助!

1个回答

3
我假设你已经尝试在回调函数中使用 i 和< i>j ,但总是发现它们等于最后一个值;这是因为JavaScript只有函数作用域(而不是块作用域),所以< i>i 和< i>j 只被声明一次;因此,每次迭代都引用相同的变量。
想了解更多信息,请参见 Doesn't JavaScript support closures with local variables?
解决方案与示例中相同(以及所有出现此问题的情况); 您需要引入新的作用域级别。您可以通过以下方式很好地解决您的问题;
function buildResponseFor(i) {
    return function (response, status) {
        if (status == google.maps.DistanceMatrixStatus.OK) {
            var distances = response.rows[0].elements;

            // Use i here.
        }
    }
}

然后更新你的getDistanceMatrix调用为:

distMatrix.getDistanceMatrix({
    origins: origin, // array containing single lat/lng
    destinations: destinations,
    travelMode: google.maps.TravelMode.DRIVING,
    unitSystem: google.maps.UnitSystem.IMPERIAL,
    avoidHighways: false,
    avoidTolls: false

}, buildResponseFor(i));

请注意,您可以将ijij等参数传递给您的buildResponseFor函数,并在回调函数中以您在function声明中为buildResponseFor指定的名称使用它们。


太棒了!非常感谢,Matt。我确实尝试过使用i和j,但是像你说的那样,在循环中看到了最终值。我对JavaScript还比较新,所以感谢你分享这个小知识点,我相信它将再次派上用场。 - Beesknees

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接