如何使用setTimeout防止429(Too Many Requests)错误

时间:2014-08-10 10:46:37

标签: javascript

我使用的服务用同义词替换文章的文字,服务的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?有人可以向我解释为什么会这样吗?

1 个答案:

答案 0 :(得分:2)

此代码:

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

立即调用 Art.generateSector ,传递j*60,然后获取返回值< / em>并将其传递给setTimeout,与foo(bar()) 调用 bar的方式完全相同,并将其返回值传递给foo

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

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

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


Function#bind是ES5的一项功能。如果你必须支持像IE8那样的真正旧的JavaScript引擎,这个功能可以是&#34; shimmed&#34; (&#34; polyfilled&#34)。搜索&#34;功能绑定垫片&#34;或&#34;功能绑定polyfill&#34;找到多个选项。