如何在JavaScript函数中暂停FOR循环?

3

Google Places API有每秒查询限制,因此我需要减慢发送请求的循环速度:

function callback(results, status) {
  if (status != google.maps.places.PlacesServiceStatus.OK) {
    alert(status);
    return;
  }
      for (var i = 0, result; result = results[i]; i++) {
    RequestInfo(result);
  }
}

你有什么想法吗?我有点新手。


https://dev59.com/uWHVa4cB1Zd3GeqPop4X - Gloria
@Gloria 不完全正确。问题类似但意图不同。 - Evan Davis
3个回答

4

递归解决方案:

function requestInfoWrapper(results, i) {
    i = i + 1;
    if (i >= results.length) {return};
    requestInfo(results[i]);
    setTimeout(function() {requestInfoWrapper(results, i);}, 1000);
}

以下是一些示例代码,用于测试:

   var results = ["test 1", "test 2", "test 3"];
   function requestInfo(str) {console.log(str);}
   requestInfoWrapper(results, -1);

同时集成到您的代码中的只是:

function callback(results, status) {
    if (status != google.maps.places.PlacesServiceStatus.OK) {
        alert(status);
        return;
    }

    requestInfoWrapper(results, -1);
}

@CrazyTrain:虽然这只适用于results是全局作用域的情况,并且只要在最后一个setTimeout发生之前没有调用callback。;-) - Brad Christie
好的,请求信息包装函数是否能够访问结果数组呢?抱歉我有点新手。 编辑 结果不是全局作用域。 - dlofrodloh
@BradChristie:是的,我在评论初始解决方案,我认为它应该放在“callback”函数内部。最后的解决方案应修改“requestInfoWrapper”,以传递“results”数组。 - user2437417
编辑后,结果不必是全局的。 - PherricOxide

2
for (var i = 0, result; result = results[i]; i++){
    (function(result){
        setTimeout(function(){
            RequestInfo(result);
        }, 1e3 * i);
    })(result);
}

您可以使用setTimeout定时器并设置每个定时任务的间隔为1秒 * n(其中n为当前迭代次数)。

至于更加直白的回答,JavaScript没有“sleep”方法(也不应该有;它是单线程的,并会在等待期间阻塞其他任何操作)。


你遇到了“循环回调”问题。 - user2437417
@CrazyTrain:诚然,我对地图API不够熟悉,也不知道callback具体是什么;我猜你的意思是callback触发一堆RequestInfo,这些又会反过来调用callback(反复循环)? - Brad Christie
3
没有特定于API的内容。只是你将传递给setTimeout的回调函数引用了result变量,而该变量的范围限定在封闭函数内。因为这个变量在循环的每次迭代中都会被覆盖,所以当回调最终被调用时,它们将引用result最后被设置的值,即undefined - user2437417
嗯,这对我来说不起作用。1e3是什么意思?我应该将其更改为其他内容吗? - dlofrodloh
@CrazyTrain:哦,傻了。哈哈,今天没想清楚。应该修好了。;-) 用户:1e3只是表示1秒的符号(我觉得比1000更容易)。例如:半秒=0.5e3(超过500),1/4=0.25e3(超过2500),等等。 - Brad Christie
1
@user2721465:1e3只是一种有点烦人的表达方式,表示的是1000.0 - cHao

1
您可以使用setTimeout来递归调用函数。
var i = 0;
function callback(results, status) {
  if (status != google.maps.places.PlacesServiceStatus.OK) {
    alert(status);
    return;
  }
  setTimeout(function() { 
    i++; 
    if (i < results.length) { 
      RequestInfo(results[i]);
      callback(results, status);
    }
  }, 1000);
}

我猜你打算在某个地方进行递归调用? - user2437417

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