【问题标题】:How to prevent 429 (Too Many Requests) error using setTimeout如何使用 setTimeout 防止 429(请求过多)错误
【发布时间】:2014-08-10 10:46:36
【问题描述】:

我正在使用服务将文章的单词替换为同义词,该服务的 API 限制为每分钟 60 个请求。我有两个函数,第一个获取文章并将其拆分为一个数组,然后调用另一个替换单词,我尝试通过将超时设置为第二个来做到这一点,这样它将首先被调用,然后在 60 秒后调用,然后在 120 秒后……所以我每分钟最多调用该服务 60 次。

generateArticle : function(data){ 
  Art.words = data.split(" ");
  for(var j=0; j<Art.words.length/60; j+=1){
    setTimeout(Art.generateSector(j*60),j*60000);
  }
},

generateSector : function(position){
  var count = 0;
  for(var i=position; i<Art.words.length; i+=1){
    if(Art.words[i].length > 3 && isNaN(Art.words[i]) && count < 60){
      Art.findsimilarword(Art.words[i],i);
      count++;
    }
  }
},

但是发生的情况是第二个函数被立即调用,所以在一篇有 400 个单词的文章中,前 60 个单词将被正确替换,但对于其余 340 个单词,我收到错误 429 (Too Many Requests) 。我是否以错误的方式使用 setTimeout?有人可以向我解释为什么会这样吗?

【问题讨论】:

    标签: javascript


    【解决方案1】:

    这段代码:

    setTimeout(Art.generateSector(j*60),j*60000);
    

    调用Art.generateSector立即,传入j*60,然后获取其返回值和将它传递给setTimeout,就像foo(bar()) 调用 bar 并将其返回值传递给foo 一样。

    要安排对函数的调用,请传入函数引用。在您的情况下,您可能可以使用Function#bind:

    setTimeout(Art.generateSector.bind(Art, j*60),j*60000);
    

    Function#bind 返回一个新函数,在调用该函数时,将使用给定值 this(在我们的例子中为 Art)和您提供的任何其他参数调用原始函数。


    Function#bind 是一个 ES5 特性。如果您必须支持像 IE8 中的非常旧的 JavaScript 引擎,则可以“填充”(“polyfill”)此功能。搜索“function bind shim”或“function bind polyfill”以找到多个选项。

    【讨论】:

    • 或 ...setTimeout(function (){Art.generateSector(j*60)},j*60000);jsbin.com/axaluq/44?q=bind
    • @RoyiNamir:不,使用该代码,回调将使用错误的 j 值。
    • 对不起setTimeout(function (a){ return function (){Art.generateSector(a*60)}}(j),j*60000);
    • @RoyiNamir:对。但是除了我们为setTimeout 创建的函数之外,没有理由在每个循环上创建和丢弃一个临时构建器函数。只需使用bind,这就是它的用途。
    猜你喜欢
    • 2019-10-04
    • 1970-01-01
    • 2020-04-24
    • 2014-05-12
    • 2020-05-26
    • 1970-01-01
    • 2020-11-10
    • 1970-01-01
    相关资源
    最近更新 更多