简体   繁体   English

JavaScript 中的 setInterval 与 setTimeout 混淆

[英]Confusion of setInterval with setTimeout in JavaScript

I am trying to use 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);

I expected that the last value of one and two would be true.我预计一和二的最后一个值是正确的。

I expected that every time when the logger print, both one and two have the same value of the third parameter, that means target equals temArr[temArr.length - 1]我希望每次记录器打印时,一和二都具有相同的第三个参数值,这意味着target equals temArr[temArr.length - 1]

But the result is that one is true, and two is false但是结果是一个是真的,两个是假的

But the intermediate result of two is false, and the last value is true, while one is alway true但是两个的中间结果是假的,最后一个值为真,而一个总是真

When I switch the timeout value,当我切换超时值时, and the result is true结果是真的that means set the interval with value 500 and the timeout with value 100 , at this time both target === temArr[temArr.length - 1] is alway true every time the logger print这意味着将间隔设置为500 ,将超时设置为100 ,此时每次记录器打印时target === temArr[temArr.length - 1]都始终为真

could you please tell me why?你能告诉我为什么吗?

They both returned true for me, just different order:他们都为我返回了 true,只是顺序不同:

Ok setInterval VS setTimeout :好的setInterval VS setTimeout

setInterval - will run the function inside EVERY x ms. setInterval - 将在每x毫秒内运行 function。 which means:意思是:

setInterval(() => {
  console.log('I will run every 100ms')
}, 100)

Will run EVERY 100ms.将每 100 毫秒运行一次。

setTimeout - will run the function inside AFTER x ms. setTimeout - 将在x毫秒后运行 function。 which means:意思是:

setTimeout(() => {
   console.log('I will run after 10 seconds')
}, 10000);

will run AFTER 10 seconds.将在 10 秒后运行。


So doing this:所以这样做:

let timer = setInterval(() => {
  console.log('I will run every 500ms';   

  setTimeout(() => {
    cosole.log('I will run AFTER 500ms EVERY 500ms');
  }, 500);
}, 100)

The log inside setTimeout will run 500ms AFTER the first log has been triggered and will trigger every 100ms. setTimeout中的日志将在第一个日志被触发后运行 500 毫秒,并且每 100 毫秒触发一次。


EDIT - Answer to user's edited question:编辑 - 回答用户编辑的问题:

For clearer logs, I modified your code:为了更清晰的日志,我修改了您的代码:

 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);

Notice how TWO - SET TIMEOUT doesn't fetch the same result as ONE - SET TIMEOUT ?请注意TWO - SET TIMEOUT如何获取与ONE - SET TIMEOUT不同的结果? It's because it doesn't fetch the value of that variable when it was called but it fetches ON TRIGGER which means that the value already changed because setInterval has shorter time.这是因为它在调用时没有获取该变量的值,但它获取了 ON TRIGGER 这意味着该值已经更改,因为setInterval的时间更短。

What you can do for this is to call the setTiemout on a different function so it will reference its value on the parameter instead of the newly generated one.为此,您可以做的是在不同的setTiemout上调用 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);

^^ on the snippet above, the target and result are now the same for both logs. ^^ 在上面的片段中,两个日志的目标和结果现在相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM