我对setTimeout
的工作方式感到有些困惑。我试图在一个循环中有一个setTimeout
,所以循环迭代比如相隔1秒。
每个循环迭代发出一个HTTP请求,似乎另一端的服务器无法在如此短的时间内处理那么多请求。
for (var i = 1; i<=2000 && ok; i++) {
var options = {
host:'www.host.com',
path:'/path/'+i
};
setTimeout(makeRequest(options, i), 1000);
};
为什么这不起作用,我该如何实现?
谢谢
答案 0 :(得分:11)
setTimeout 非阻止,它是异步的。你给它一个回调,当延迟结束时,你的回调就会被调用。
以下是一些实现:
您可以在setTimeout
回调中使用recursive call。
function waitAndDo(times) {
if(times < 1) {
return;
}
setTimeout(function() {
// Do something here
console.log('Doing a request');
waitAndDo(times-1);
}, 1000);
}
以下是如何使用您的功能:
waitAndDo(2000); // Do it 2000 times
关于堆栈溢出错误:setTimeout
清除调用堆栈(请参阅this question),这样您就不必担心{{1}上的堆栈溢出递归调用。
如果您已经在使用io.js(&#34;下一个&#34;使用ES6的Node.js),您可以使用优雅的解决方案解决您的问题而无需递归:
setTimeout
以下是如何使用您的功能(使用co):
function* waitAndDo(times) {
for(var i=0; i<times; i++) {
// Sleep
yield function(callback) {
setTimeout(callback, 1000);
}
// Do something here
console.log('Doing a request');
}
}
BTW:这实际上是在使用循环;)
答案 1 :(得分:8)
你需要这样的东西
var counter = 5;
function makeRequst(options, i) {
// do your request here
}
function myFunction() {
alert(counter);
// create options object here
//var options = {
// host:'www.host.com',
// path:'/path/'+counter
//};
//makeRequest(options, counter);
counter--;
if (counter > 0) {
setTimeout(myFunction, 1000);
}
}
在alert(count);
点,你可以打电话给服务器。
请注意,计数器的工作方式相反(倒计时)。我更新了一些
评论在哪里做你的事。
答案 2 :(得分:3)
现在,您正在安排所有请求同时发生,在脚本运行后仅一秒钟。您需要执行以下操作:
var numRequests = 2000,
cur = 1;
function scheduleRequest() {
if (cur > numRequests) return;
makeRequest({
host: 'www.host.com',
path: '/path/' + cur
}, cur);
cur++;
setTimeout(scheduleRequest, 1000)
}
请注意,每个后续请求仅在当前请求完成后安排。
答案 3 :(得分:1)
你在setTimeout调用中调用makeRequest() - 你应该将函数传递给setTimeout,而不是调用它,所以像
这样的东西setTimeout(makeRequest, 1000);
没有()
答案 4 :(得分:1)
我很惊讶没有人提到过这个,但听起来你需要setInterval而不是setTimeout。
vat poller = setInterval(makeRequestFunc, 3000)
上面的代码每隔3秒发出一次请求。由于您将对象保存到变量poller
,因此可以通过清除对象来停止轮询:
cleanInterval(poller)
答案 5 :(得分:0)
let i = 20;
let p = Promise.resolve(i)
while (i > 0) {
(i => {
p = p.then(() => {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log(i);
resolve()
}, 2000)
})
})
})(i)
i--
}
p = p.then(data => console.log('execution ends'))
答案 6 :(得分:0)
我在这个问题上很晚了(像往常一样...;),但是我发现将请求循环到慢速响应API并在没有HTTP 504的情况下获取响应的唯一方法是使用promises。
async function LoadDataFromAPI(myParametersArray) {
for(var i = 0; i < myParametersArray.length; i++) {
var x = await RunOneRequest(myParametersArray[i]);
console.log(x); // ok
}
}
异步函数调用的函数:
function RunOneRequest(parameter) {
return new Promise(resolve => {
setTimeout(() => {
request(parameter, (error, response, body) => {
// your request
});
resolve('ok);
}, 2000); // 2 secs
});
}