尝试在javascript中使用带有for循环的time.js仅输出数组

时间:2018-04-02 18:49:29

标签: javascript for-loop foreach

我正在使用一个名为timer.js的库,因为我想遍历一个数组,但希望在迭代之间有一个延迟

这是图书馆的github:https://github.com/husa/timer.js

的链接

我做了什么,从我的主要js文件之前创建了一个文件形式的最小版本的timer.js并链接到它的html主体:

<script src="./timer.js" charset="utf-8"></script>
<script src="./script.js" charset="utf-8"></script>

然后在主js文件中我创建了一个数字数组,我只想循环遍历它们,同时在console.logs之间有一个间隔:

var timer = new Timer();

var nums = [1,2,3,4]

for (var i = 0; i < nums.length; i++){
  timer.start(5).on('end', function(){
    console.log(i);
  })
}

当我打开控制台日志时,我只得到一个&#39; 4&#39;登录。为什么for循环不适用于其他索引。另外,有没有办法用forEach函数重新创建它?

谢谢

2 个答案:

答案 0 :(得分:1)

  

我想循环遍历一个数组,但希望在迭代之间有一个延迟

根据迭代设置持续时间:

duration*iteration

setTimeout可以实现延迟,持续时间以毫秒为单位,比如说2秒(2000ms),让我们为迭代添加1,这样第一次迭代就会有延迟:

const nums = [1,2,3,4]

nums.forEach((n, i)=>{
  setTimeout(()=>(
    console.log(i)
  ), 2000*(i+1))
});

答案 1 :(得分:1)

在处理异步代码时,你遇到了一些常见的陷阱。

首先要意识到你的for循环是而不是等待每次迭代完成。它只是尽可能快地调用timer.start(5)四次。为此,您不能使用for循环。您最好的选择是使用非常受欢迎的async库中的内容。

要意识到的第二件事是你在同一个实例上重复调用start(5),导致它每次重置为5秒。因此,只有一个预定的回调被调用,循环完成后五秒。这实际上不是对异步代码的误解,而是对timer.js库本身的误解。您可以通过在循环中创建新的计时器来解决此问题,但对于您的情况timer.js有点矫枉过正。您可以使用原生setTimeout来电完全按照您的要求执行操作。

要实现的第三件事是,您发送给on()的回调不会存储i的当前值。它只是存储对该变量的引用,因此对该变量的任何更改最终都会反映在日志中。

在循环的最后一次迭代期间,i的值实际上是3而不是4.这是因为4不是< nums.length。那么,执行的唯一回调应该记录3,对吗?

但是,不是那么快。循环在每次迭代后总是做的最后一件事是增加i的值。因此,i从3变为4,然后检查它是否为< nums.length,并且由于它不是,它会退出。然后,五秒钟后,您的回调会记录i的值,现在为4。

这是Javascript中名为closure的属性。我绝对建议阅读该链接,因为这个概念对于有效使用该语言非常重要。

无论如何,因为您可能正在寻找正确的代码,所以我会使用asyncsetTimeout来执行您尝试的操作:

var nums = [1,2,3,4];

async.eachSeries(nums, (num, done) => {
    setTimeout(() => {
        console.log(num);
        done();
    }, 5000);
});