我如何知道最后一个异步函数何时在ob" for键中返回结果?循环

How do I know when the last asynchronous function has returned results in the "for key in ob" loop?

本文关键字:for 返回 循环 结果 quot 最后一个 何知道 异步 函数 ob 何时      更新时间:2023-09-26

我有下面的代码来遍历一个对象:

var data = [];
var obj = {...
};
for (var key in obj) {
  if (!obj[key]["something"]) {
    geocoder.geocode({
      'address': key
    }, function(results, status) {
      if (status === google.maps.GeocoderStatus.OK) {
         data.push({...});
      }
    });
    // if last item
    $.post("...", data, ...);
  }
}

现在我想发布通过运行循环中调用的所有异步函数获取的所有数据。

由于geocoder.geocode()(这是Google Maps API的一部分)不返回PromiseDeferred,您必须将请求封装在您自己的Promise中,然后使用Promise.all():

var promises = [];
for (var key in obj) {
    if (!obj[key]["something"]) {
        promises.push(new Promise(function (resolveWith, rejectWith) {
            geocoder.geocode({
                'address': key
            }, function (results, status) {
                if (status === google.maps.GeocoderStatus.OK) {
                    data.push(...);
                    resolveWith(results);
                } else
                    rejectWith(results);
            });
        }));
    }
}
Promise.all(promises).then(function (resultsArr) {
    // at this point all requests have been fulfilled
    $.post(...);
});

看到MDN

尝试使用jQuery.Deferred()

var obj = {...};
var deferred = $.Deferred();
deferred.done(function(){ /*.. asynchronous function here ..*/ });
for (var key in obj) {
  if (!obj[key]["something"]) {
    deferred.resolve();
  }
}

您需要知道哪个键是最后一个,但由于对象中散列键没有确定的顺序,因此在边缘情况下很可能不会出现您想要的结果。

至少获得某种最后键的一种方法是在主循环之前迭代一次,如下所示:

var obj = {...
};
var lastkey;
for (var key in obj) {
  lastkey = key;
}
for (var key in obj) {
  if( key === lastkey) {
    ... do lastkey stuff instead here
  } else {
    if (!obj[key]["something"]) {
      geocoder.geocode({
        'address': key
      }, function(results, status) {
        if (status === google.maps.GeocoderStatus.OK) {
       ...
        }
      });
    }
  }
}

如果'obj'在这两个循环期间或之间没有改变,那么最后一个键在两个循环中应该是相同的。

 var data = [];
 var obj = {...
 };
var keys = Object.keys(obj);
 var last = keys[keys.length-1];
for (var key in obj) {
if (!obj[key]["something"]) {
geocoder.geocode({
  'address': key
}, function(results, status) {
  if (status === google.maps.GeocoderStatus.OK) {
     data.push({...});
  }
});
// if last item
if (key == last)
$.post("...", data, ...);
 } 
 }