如何重新构建此 for 循环,以便在异步 api 调用完成之前不会进行下一次迭代

How to re-structure this for loop so the next iteration doesn't happen until an asynchronous api call completes

本文关键字:一次 迭代 for 循环 构建 何重新 api 调用 异步      更新时间:2023-09-26

所以下面我们有学校一个数组,比如school[key] = value。

for(key in schools) {
        geocoder = new google.maps.Geocoder();
        var address = schools[key];
        var org_code = key;
        geocoder.geocode({ 'address': address}, function(results, status) {
             //callback function
        })
}

我需要在回调函数中使用键/org_code,但显然 for 循环的迭代速度比地理编码 api 调用完成的速度快,因此在回调函数中使用了不正确的键。

我尝试使用 array.shift 将上述内容重写为函数并在回调中使用该函数,但我无法做到......一方面,我无法使用该方法访问密钥。

您可以使用闭包:

for(key in schools) {
    (function(key) {
        geocoder = new google.maps.Geocoder();
        var address = schools[key];
        var org_code = key;
        geocoder.geocode({ 'address': address}, function(results, status) {
            //callback function
        })
    })(key)
}

使用立即调用的函数表达式创建闭包,为每次迭代限定变量范围:

for (key in schools) {
    geocoder = new google.maps.Geocoder();
    var address = schools[key];
    var org_code = key;
    (function(address, org_code) {
        geocoder.geocode({
            'address': address
        }, function (results, status) {
            //callback function
        })
    })(address, org_code);
}

使用闭包的另一个建议:

for(key in schools) {
    geocoder = new google.maps.Geocoder();
    var address = schools[key];
    var org_code = key;
    geocoder.geocode({ 'address': address }, function(org_code, address) {
        return function (results, status) {
            // use address and org_code here
        };
    }(org_code, address))
}

使用递归函数。要获取密钥 - 重新格式化学校数组。

var geocoder = new google.maps.Geocoder();
function geocodeNext(sch) {
  var item = sch.shift();
  var address = item['address'];
  var key = item['key'];
  geocoder.geocode({ 'address': address}, function(results, status) {
    //do something with key
    geocodeNext(sch);
  })
}
var schools1 = [];
for var (key in schools) {
  schools1.push({'address': schools[key], 'key': key});
}
geocodeNext(schools1);