我有这段代码:
times.forEach(function(element) {
setTimeout(function() { alert(element); }, element * 1000);
});
和这个数组:[1, 5, 1]
我预计会有一个警报,首先是1秒后,然后是第一个之后的另一个警报,第二个之后是1秒后的最后一个警报,但是与1的相关的警报在开始时一起显示...有什么帮助吗?
答案 0 :(得分:1)
你必须记住一个非常重要的事情:javascript的执行是异步的。带警报的示例中的setTimeout会导致混淆。我猜您期望以下内容:
1秒超时
警报1
1秒超时
警报2
1秒超时
警报3
然而,现实中发生的事情如下:
1秒超时开始,2秒超时开始,3秒超时开始
警报1< - 这需要一些时间来显示,你必须点击“确定”
?超时,取决于你对警报1作出反应的时间
警报2< - 可能在alert1之后
?超时
alert3< - 如果事件被“堆积”,这甚至可能在 alert2之前发生
要检查,如果您的代码有效,请不要使用警报,而应使用不会像console.log()
那样干扰的警告。
times = [1,2,3];
times.forEach(function(element) {
setTimeout(function() { document.write(element); }, element * 1000);
});
如果您希望在之后有保证的时间范围,则可以
1)在警报关闭后触发下一个超时 - 或者更好 -
2)使用挂钩到“alert close”事件的回调。
答案 1 :(得分:1)
编辑:答案原本适用于数组[1, 2, 3]
,但它适用于任意数值。
现在,你几乎在同一时刻开始每一次超时:
"现在"并没有明显的改变。这将有效地产生流行音乐之间1秒的差异。要链接这些超时,您可能会执行以下操作。
您可以考虑先前的值,但仍然可以在同一时刻开始所有超时:
var chainDelay = 0;
times.forEach(function (element) {
setTimeout(function () { alert(element); }, (element + chainDelay) * 1000);
chainDelay += element;
});
...或者你可以这样做,以便只在前一个被触发时才开始新的超时:
function timeoutHandle(array, index) {
if (index < array.length) {
alert(array[index]);
setTimeout(timeoutHandle, array[index] * 1000, array, index);
}
}
setTimeout(timeoutHandle, times[0] * 1000, times, 0);
答案 2 :(得分:0)
您可以使用reduce来实现您想要的方式:
[1, 5, 1].reduce(function(p, c, i) {
setTimeout(function() {
document.write(`element: ${c} <br>`);
}, (p + c) * 1000);
return p + c;
}, 0);
答案 3 :(得分:0)
使用lodash或其他一些东西来获得干净的代码:
var times = [1, 3, 1];
times.forEach(function(item) {
_.delay(function() {
alert(new Date() + ' : ' +item);
}, item*1000);
});
&#13;
<script src="https://raw.githubusercontent.com/lodash/lodash/4.11.1/dist/lodash.js"></script>
&#13;
答案 4 :(得分:-4)
如你所愿(:
function alertDelayed(text, delay) {
setTimeout(function() {
alert(new Date() + text);
}, delay);
}
var times = [1, '5', '1anything']; // array can be different, so parseInt will sanitize it insidoe of foreach.
var previousElement = 0;
times.forEach(function(element) {
alertDelayed(element, previousElement*1000 + parseInt(element)*1000); // alert after element seconds after previous alert
previousElement = parseInt(element);
});