我有一个html文件,上面有一个按钮
<!DOCTYPE html>
<html> <body>
<p>Click the button to list all the items in the array.</p>
<button onclick = "numbers.forEach(myFunction)" >Try it</button>
<p id="demo"></p>
</body>
</html>
我还有一个Javascript文件,其中包含onclick
方法的.forEach
函数
单击按钮时,我想通过一个数组,循环遍历数组中每个元素实例。
对于这个数组中的每个元素,我想用一个计时器打印出它的索引和值,然后等待一秒钟以显示下一个排列。
demoP = document.getElementById("demo");
var numbers = [];
var random = Math.floor(Math.random() * 4) + 1;
numbers.push(random);
function myFunction(item, index) {
random = Math.floor(Math.random() * 4) + 1;
numbers.push(random);
demoP.innerHTML = demoP.innerHTML + "numbers[" + index + "]: " + item + "<br>";
//demoP.innerHTML = demoP.innerHTML + "<br>" //add magic spacing between permutation
sleep(100);
//switch to this and see how slow?
//sleep(1000);
}
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
我希望用户点击按钮时显示的结果是:
numbers[0] = 4
//waits a second and adds a <br> here to separate
numbers[0] = 4
numbers[1] = 2
//waits a second and adds a <br> here
numbers[0] = 4
numbers[1] = 2
numbers[2] = 3
等等。
目前,代码输出的元素数量至少是其两倍,而sleep()的持续时间似乎比它应该长。
答案 0 :(得分:4)
除了可怕的sleep
功能。您使用myFunction
作为forEach
的回调,而在myFunction
中,您正在将新元素推送到numbers
,这与您呼叫的同一个数组forEach
上。
forEach
在仍然循环数组的同时,不会对新推送的项目调用回调。但是在循环结束时,数组中的项目将加倍。根据MDN的说法:
forEach()
处理的元素范围在第一次调用callback
之前设置。forEach()
将不会访问在callback
调用开始后附加到数组的元素。
如果数组包含N
个元素,那么当点击发生时,N
元素将会显示,myFunction
会推送N
个其他元素,并且当下一个元素时点击发生2N
这次将显示元素,...
因此,每次单击后,数组中的元素将加倍。