【问题标题】:How to pause a FOR loop in Javascript in a function?如何在函数中暂停 Javascript 中的 FOR 循环?
【发布时间】:2013-09-01 01:39:37
【问题描述】:

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);
  }
}

知道我该怎么做吗?我是个新手。

【问题讨论】:

标签: javascript google-places-api


【解决方案1】:

递归解,

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。 ;-)
  • 好的,但是 requestInfoWrapper 函数可以访问结果数组吗?对不起,我有点新手。 edit 结果不是全局范围
  • @BradChristie:是的,我在评论最初的解决方案,我认为它应该放在callback 函数中。最后一个解决方案应该修改requestInfoWrapper以传入results数组。
  • 已编辑,因此结果不必是全局的。
【解决方案2】:
for (var i = 0, result; result = results[i]; i++){
    (function(result){
        setTimeout(function(){
            RequestInfo(result);
        }, 1e3 * i);
    })(result);
}

您可以使用setTimeout 并将它们隔开以执行每个1 second * n(其中n 是当前迭代次数)。

而且,更重要的是,JavaScript 没有“睡眠”方法(您也不希望它有;它是单线程的,在等待时会占用其他任何东西)。

【讨论】:

  • 你遇到了“循环回调”问题。
  • @CrazyTrain: 诚然,我对地图 API 不够熟悉,也不知道确切callback 是什么;我假设您的意思是回调会触发一堆RequestInfo,而后者又会调用回调(起泡、冲洗、重复)?
  • 没有特定于 api 的内容。只是您传递给setTimeout 的回调引用了result 变量,该变量的作用域为封闭函数。因为变量在循环的每次迭代中都会被覆盖,所以当最终调用回调时,它们将引用 result 设置的最后一个值,即 undefined。
  • Hrm,这对我不起作用。 1e3 位是什么?我应该将其更改为其他内容吗?
  • @user2721465: 1e3 只是拼写1000.0 有点烦人的方式。
【解决方案3】:

您可以使用 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);
}

【讨论】:

  • 我假设您打算在某处进行递归调用?
猜你喜欢
  • 2020-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多