同一循环中两个不同的超时

时间:2018-11-04 17:40:26

标签: javascript node.js

我有一个运行良好的网络搜寻器,但是我遇到了问题。我基本上需要的是,当我达到90个请求时,我需要给出5分钟或更长时间的超时。

我的示例代码:

for (let i=0; i < maxPag; i++) {
    setTimeout(function(){
        console.log(i);
        getInfoPage(i);

    }, 15000 * (i+1));
} 

例如,在上面的示例中,我给出了超时,但是是针对请求的页面,但是在90个请求之后,我需要有一个更大的超时,这种情况在我达到90个请求的所有时间都会发生。 >

如何在第90个请求中而不是在第180个请求中进行间隔,一直到我的for循环结束。

5 个答案:

答案 0 :(得分:2)

您可以使用一个循环,该循环在第90次迭代中等待的时间更长:

 const timer = ms => new Promise(res => setTimeout(res, ms));

 (async function() {
    for(let i = 0; i < maxPag; i++) {
       if(i && !(i % 90)) {
          await timer(5 * 60 *1000);
       } else {
           await timer(15000);
       }
       getInfoPage(i);
    }
 })();

答案 1 :(得分:2)

除了async / await方法之外,您还可以将以下解决方案与朴素的setTimeout计划结合使用:

for (let i=0; i < maxPag; i++) {
    setTimeout(function(){
        console.log(i);
        getInfoPage(i);

    }, 15000 * (i+1) + 300000 * Math.floor(i / 90));
//     ^^^^^           ^^^^^^
// 15s between each    5m between chunks of 90
}

答案 2 :(得分:2)

最简单,最干净和推荐的解决方案是使用递归函数:

var i = 0;
var BATCH_SIZE = 90;
var TIMEOUT_NORMAL = 15000;
var TIMEOUT_LONG =  300000;

function crawl() {
    // Your crawling code
    console.log(i);
    getInfoPage(i);

    // Schedule next call (if there are still pages left)
    if (++i < maxPag) {
        // Use the longer timeout if "i" is divisible by 90
        setTimeout(crawl, i % BATCH_SIZE ? TIMEOUT_NORMAL : TIMEOUT_LONG);
    }
}

// Start the crawler
crawl();

使用递归函数超时可以最大程度地控制循环,并使代码更易于理解。

我使用了索引i作为全局变量,以简化setTimeout的调用,并且代码将更加高效,因为您不必传递任何参数并保存任何变量堆栈。请注意,不建议像我上面那样全局定义变量,您应该将所有变量都写在命名空间中,例如:

var crawlOpts = {
    currentIndex: 0,
    BATCH_SIZE: 90,
    TIMEOUT_NORMAL: 15000,
    TIMEOUT_LONG:  300000,
}

并像crawlOpts.BATCH_SIZEcrawlOpts.currentIndex++一样访问它们。

答案 3 :(得分:0)

使用async/await并递归运行函数:

console.clear()
const maxPag = 10000;
const timeoutAfter = 10;
const timeoutTime = 1000


const timeout = ()=>new Promise(resolve=>setTimeout(resolve, timeoutTime))
const run = async (i=0) => {
    console.log(i)
    getInfoPage(i);
    if (i%timeoutAfter === 0){
      await timeout()
    }
    run(++i)
}

run()

这里是jsfiddle

答案 4 :(得分:0)

let extraTimeOut = 0

for (let i = 0; i < maxPag; i++) {
  if(i && i % 90 === 0) {
    extraTimeOut += 300000
  }

  setTimeout(function() {
    console.log(i);
    getInfoPage(i);

  }, 1500 * (i + 1) + extraTimeOut);
}