JavaScript 中 setInterval 与 setTimeout 的混淆
Confusion of setInterval with setTimeout in JavaScript
我正在尝试在 JavaScript 中使用 setInterval 和 setTimeout。
var temArr = []
let timer = setInterval(() => {
var target = Math.random()
temArr.push(target)
console.log(6, target, temArr[temArr.length - 1], target === temArr[temArr.length - 1]) // one
setTimeout(() => {
console.log(9, target, temArr[temArr.length - 1], target === temArr[temArr.length - 1]) // two
}, 500);
}, 100)
setTimeout(() => {
clearInterval(timer)
}, 10000);
我预计一和二的最后一个值是真的。
我预计每次记录器打印时,一和二的第三个参数值相同,即target equals temArr[temArr.length - 1]
但结果是一个为真,两个为假
但是二的中间结果为假,最后一个值为真,而一始终为真
当我切换超时值时,结果为真,这意味着设置间隔值 500
和超时值 100
,此时,每次记录器打印时,target === temArr[temArr.length - 1]
始终为真
你能告诉我为什么吗?
它们都为我返回了 true,只是顺序不同:
还行 setInterval
VS setTimeout
:
setInterval
- 将 运行 每 x
毫秒内的函数。这意味着:
setInterval(() => {
console.log('I will run every 100ms')
}, 100)
将 运行 每 100 毫秒。
setTimeout
- 将 运行 函数在 x
毫秒之后。这意味着:
setTimeout(() => {
console.log('I will run after 10 seconds')
}, 10000);
将在 10 秒后 运行。
这样做:
let timer = setInterval(() => {
console.log('I will run every 500ms';
setTimeout(() => {
cosole.log('I will run AFTER 500ms EVERY 500ms');
}, 500);
}, 100)
setTimeout
中的日志将在第一个日志被触发后 运行 500 毫秒,并且每 100 毫秒触发一次。
编辑 - 对用户编辑问题的回答:
为了更清晰的日志,我修改了你的代码:
var temArr = []
var intervalOrder = 0;
var timeoutOrder = 0;
var timer = setInterval(() => {
var target = Math.random()
temArr.push(target)
intervalOrder++
console.log('ONE - SET TIMEOUT: ', {order: intervalOrder, target, tem: temArr[temArr.length - 1], result: target === temArr[temArr.length - 1]})
setTimeout(() => {
timeoutOrder++
console.log('TWO - SET TIMEOUT: ', {order: timeoutOrder, target, tem: temArr[temArr.length - 1], result: target === temArr[temArr.length - 1]}) // two
}, 500);
}, 100)
setTimeout(() => {
clearInterval(timer)
}, 1000);
注意到 TWO - SET TIMEOUT
与 ONE - SET TIMEOUT
获取的结果不同吗?这是因为它在调用时不获取该变量的值,但它获取 ON TRIGGER 这意味着该值已经更改,因为 setInterval
的时间更短。
为此你可以做的是在不同的函数上调用 setTiemout
,这样它将在参数而不是新生成的参数上引用它的值。
var temArr = []
var intervalOrder = 0;
var timeoutOrder = 0;
var logSecond = (target) => {
setTimeout(() => {
timeoutOrder++
console.log('TWO - SET TIMEOUT: ', {order: timeoutOrder, target, tem: temArr[temArr.length - 1], result: target === temArr[temArr.length - 1]}) // two
}, 500);
}
var timer = setInterval(() => {
var target = Math.random()
temArr.push(target)
intervalOrder++
console.log('ONE - SET TIMEOUT: ', {order: intervalOrder, target, tem: temArr[temArr.length - 1], result: target === temArr[temArr.length - 1]})
logSecond(target)
}, 100)
setTimeout(() => {
clearInterval(timer)
}, 1000);
^^ 在上面的代码片段中,两个日志的目标和结果现在相同。
我正在尝试在 JavaScript 中使用 setInterval 和 setTimeout。
var temArr = []
let timer = setInterval(() => {
var target = Math.random()
temArr.push(target)
console.log(6, target, temArr[temArr.length - 1], target === temArr[temArr.length - 1]) // one
setTimeout(() => {
console.log(9, target, temArr[temArr.length - 1], target === temArr[temArr.length - 1]) // two
}, 500);
}, 100)
setTimeout(() => {
clearInterval(timer)
}, 10000);
我预计一和二的最后一个值是真的。
我预计每次记录器打印时,一和二的第三个参数值相同,即target equals temArr[temArr.length - 1]
但结果是一个为真,两个为假
但是二的中间结果为假,最后一个值为真,而一始终为真
当我切换超时值时,结果为真,这意味着设置间隔值 500
和超时值 100
,此时,每次记录器打印时,target === temArr[temArr.length - 1]
始终为真
你能告诉我为什么吗?
它们都为我返回了 true,只是顺序不同:
还行 setInterval
VS setTimeout
:
setInterval
- 将 运行 每 x
毫秒内的函数。这意味着:
setInterval(() => {
console.log('I will run every 100ms')
}, 100)
将 运行 每 100 毫秒。
setTimeout
- 将 运行 函数在 x
毫秒之后。这意味着:
setTimeout(() => {
console.log('I will run after 10 seconds')
}, 10000);
将在 10 秒后 运行。
这样做:
let timer = setInterval(() => {
console.log('I will run every 500ms';
setTimeout(() => {
cosole.log('I will run AFTER 500ms EVERY 500ms');
}, 500);
}, 100)
setTimeout
中的日志将在第一个日志被触发后 运行 500 毫秒,并且每 100 毫秒触发一次。
编辑 - 对用户编辑问题的回答:
为了更清晰的日志,我修改了你的代码:
var temArr = []
var intervalOrder = 0;
var timeoutOrder = 0;
var timer = setInterval(() => {
var target = Math.random()
temArr.push(target)
intervalOrder++
console.log('ONE - SET TIMEOUT: ', {order: intervalOrder, target, tem: temArr[temArr.length - 1], result: target === temArr[temArr.length - 1]})
setTimeout(() => {
timeoutOrder++
console.log('TWO - SET TIMEOUT: ', {order: timeoutOrder, target, tem: temArr[temArr.length - 1], result: target === temArr[temArr.length - 1]}) // two
}, 500);
}, 100)
setTimeout(() => {
clearInterval(timer)
}, 1000);
注意到 TWO - SET TIMEOUT
与 ONE - SET TIMEOUT
获取的结果不同吗?这是因为它在调用时不获取该变量的值,但它获取 ON TRIGGER 这意味着该值已经更改,因为 setInterval
的时间更短。
为此你可以做的是在不同的函数上调用 setTiemout
,这样它将在参数而不是新生成的参数上引用它的值。
var temArr = []
var intervalOrder = 0;
var timeoutOrder = 0;
var logSecond = (target) => {
setTimeout(() => {
timeoutOrder++
console.log('TWO - SET TIMEOUT: ', {order: timeoutOrder, target, tem: temArr[temArr.length - 1], result: target === temArr[temArr.length - 1]}) // two
}, 500);
}
var timer = setInterval(() => {
var target = Math.random()
temArr.push(target)
intervalOrder++
console.log('ONE - SET TIMEOUT: ', {order: intervalOrder, target, tem: temArr[temArr.length - 1], result: target === temArr[temArr.length - 1]})
logSecond(target)
}, 100)
setTimeout(() => {
clearInterval(timer)
}, 1000);
^^ 在上面的代码片段中,两个日志的目标和结果现在相同。