我有一个运行良好的网络搜寻器,但是我遇到了问题。我基本上需要的是,当我达到90个请求时,我需要给出5分钟或更长时间的超时。
我的示例代码:
for (let i=0; i < maxPag; i++) {
setTimeout(function(){
console.log(i);
getInfoPage(i);
}, 15000 * (i+1));
}
例如,在上面的示例中,我给出了超时,但是是针对请求的页面,但是在90个请求之后,我需要有一个更大的超时,这种情况在我达到90个请求的所有时间都会发生。 >
如何在第90个请求中而不是在第180个请求中进行间隔,一直到我的for循环结束。
答案 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_SIZE
或crawlOpts.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);
}