【发布时间】:2019-03-20 04:18:10
【问题描述】:
我正在尝试迭代一个数组,然后在每次迭代中执行 2 个步骤(我们称之为第 1 步和第 2 步)。每次迭代之间以及步骤 1 和步骤 2 之间应该有一个延迟。为了添加延迟,我使用 setTimeout() 方法。
基本上,类似于 -
对于i从0到array.length
执行步骤 1
等待 2-5 秒
执行第 2 步并增加 i
等待 5-9 秒,然后继续循环
下面是我的代码(来自相关问题-How to run setTimeout() with a random interval in each iteration in javascript?)-
function displayValue(){
var l = ['a' , 'b', 'c'];
var delay = 17000;
var i = 0;
function timerFunction(i){
if(i === l.length)
return;
setTimeout(()=>{
console.log("Step 1 - Iteration - " + i + " - " + l[i] + " - " + new Date().getHours() + ":" + new Date().getMinutes() + ":" + new Date().getSeconds());
setTimeout(() => {
console.log("Step 2 - Iteration - " + i + " - " + l[i] + " - " + new Date().getHours() + ":" + new Date().getMinutes() + ":" + new Date().getSeconds());
//i++ should probably be here but then i is never incremented
}, 2000 + Math.floor(Math.random() * 3000));
i++;
timerFunction(i);
}, delay);
delay = 5000 + Math.floor(Math.random() * 3500);
}
timerFunction(i);
}
displayValue();
当我运行上述代码时,第 2 步在第 1 步之前打印,用于第一次之后的所有迭代,并且循环运行超过 array.length。输出类似于 -
第 1 步 - 迭代 - 0 - a - 9:17:14
第 2 步 - 迭代 - 1 - b - 9:17:18
第 1 步 - 迭代 - 1 - b - 9:17:21
第 2 步 - 迭代 - 2 - c - 9:17:24
第 1 步 - 迭代 - 2 - c - 9:17:28
第 2 步 - 迭代 - 3 - 未定义 - 9:17:30
我怀疑这是因为,我需要在内部 setTimeout() 中增加 i,但是当我将 i++; 移动到那里时,它可能会完全停止增加,因为它成为该方法中的局部变量。有没有办法在内部 setTimeout() 中通过引用传递 i?或者其他一些解决方案,以防我完全关闭?
【问题讨论】:
-
您是否尝试过将这些变量置于函数全局范围之外?
-
您的预期输出是什么?很难理解你想做什么。对于您的情况,您可能首先计算所有步骤的延迟时间,然后同时在同一级别调度所有 setTimeout。
-
您是否考虑过研究 javascript 迭代器?似乎它们会VASTLY 简化代码的实现,因为您只需请求集合中的下一项。您可以循环执行,退出循环,执行其他操作,请求下一个项目并得到您想要的。这似乎很有帮助,因为您可以避免所有可怕的嵌套间隔代码。更多信息:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
-
与此同时...您为自己创建的问题确实是一种竞争条件。为了在本质上都是异步的两位代码中使用相同的变量(在这种情况下为
i),您必须将内部函数包装在称为闭包的结构中。最简单的方法是使用IIFE。 -
@enhzflep 我看不到迭代器如何帮助“大大简化 [ing]”这段代码。他们仍然需要两个嵌套的 setTimeouts,迭代数组并不是这里的难点。你能分享一个例子吗?我想我错过了什么。
标签: javascript