定时每多少秒发送一个请求 的两种写法
写法一,for循环
for (let i = 0; i < 10; i++) {
setTimeout(() => {
console.log(i);
}, 2000 * i);
}
onClick();
写法二,递归函数
function demo(index) {
console.log(index)
if (index == 10) {
return
}
setTimeout(() => {
demo(index + 1);
}, 2000);
}
demo(0);
onClick();
写法一的错误示例
写法一的错误示例,问题在于 setTimeout 的回调函数都被安排在两秒后执行
for (let i = 0; i < 10; i++) {
setTimeout(() => {
console.log(i);
}, 2000);
}
onClick();
在原始的 for 循环中设置定时器会导致所有请求几乎同时启动,因为 setTimeout 函数不会阻塞代码的执行,而是将函数的执行推迟到指定的时间后。如果你在 for 循环中为每个请求设置一个定时器,所有的请求都将在大约同一时间开始,而不是依次等待前一个请求完成后再开始。
写法一的错误示例,打印的值会全为 10,并且所有数据都在两秒后同时执行
for (var i = 0; i < 10; i++) {
setTimeout(() => {
console.log(i);
}, 2000);
}
onClick();
由于 setTimeout
的回调函数是在全局作用域中执行的,它们都会访问到 for
循环结束后 i
的最终值,这通常是 10(除非循环因为某些原因提前终止)。这就是为什么你会看到所有的回调几乎同时打印出 10
的原因。
如果想要每个回调打印出它对应的迭代值,应该使用 let
而不是 var
来声明循环变量 i
,因为 let
有块级作用域,每个回调都会捕获每次迭代时 i
的值