JavaScript setTimeout()和数组

时间:2018-10-06 14:05:33

标签: javascript arrays

有人可以向我解释一下:

const array = [0, 1, 2, 4, 8, 16, 32, 16, 8, 4, 2, 1, 0];

for (let i = 0; i < array.length; i++) {
    setTimeout(function () {
        console.log(array[i]);
    }, array[i])
}

为什么返回0 1 1 0 2 2 4 4 8 8 16 16 32,而不是一一对应的数组项?

4 个答案:

答案 0 :(得分:3)

数字 依次出现。但是,您将无法看到它,因为您在它们之间设置了非常低的延迟。其中一些将一起出现。这些是与array[i]具有相同值的。

为了更好地了解它们之间的延迟,我建议将array[i]替换为array [i] * x,其中x是一个数字。看这个:

const array = [0, 1, 2, 4, 8, 16, 32, 16, 8, 4, 2, 1, 0];

for (let i = 0; i < array.length; i++) {
    setTimeout(function () {
        console.log(array[i]);
    }, array[i] * 500)
}

0×0.5 = 0秒后将回显。

1将在1×0.5 = 0.5秒后回显。

2将在2×0.5 = 1秒后回显。

4将在4×0.5 = 2秒后回显,依此类推。

编辑:如果您要询问记录0 1 1 0而不是0 0 1 1的原因,则可能是因为计算机在阵列中花了一些时间,并且在到达最后的“ 0”之前,将经过1毫秒,因此现在该记录“ 1”和“ 1”了。请注意,增加日志之间的延迟可以解决此问题。

答案 1 :(得分:0)

setTimeout()-ing时,对于浏览器,0和1实际上表示相同的东西(这就是为什么零和一开始会混合的原因)。所有其他数字都正确显示了您赋予它们的延迟,因此,首先是最小的数字(它们会先安排时间),然后是2,4,等等,这些数字会稍后出现(仅稍后一点)控制台。如果按照@WaisKamal的建议放慢速度,则此定时顺序将很明显。因此,到第二个零出现时,所有其他输出都已被调度(也就是说,setTimeouts本身都按照数组的顺序发生了),然后按时间顺序运行。

答案 2 :(得分:0)

您的代码应按递增顺序记录数组元素:

0,0,1,1,2,2,3,3,4,4,16,16,32。

如果将超时更改为更大的值,它将:

const array = [0, 100, 200, 400, 800, 1600, 3200, 1600, 800, 400, 200, 100, 0];

for (let i = 0; i < array.length; i++) {
    setTimeout(function () {
        console.log(array[i]);
    }, array[i])
}

您的代码无法按预期工作的原因是执行setTimeout回调的顺序。

您可以这样想-在setTimeout中定义的超时过去之后,将回调添加到某种队列中,该队列将尽快运行(记住js是单线程的)。在您的情况下,将数组最后一个元素的回调添加到第一个,第二个和第三个元素的回调之后的队列中(因为循环执行需要1毫秒以上的时间)。

答案 3 :(得分:-1)

这是因为循环的执行比setTimeout函数延迟要快,所以这就是延迟最小的数字优先执行的原因。