一个带整数(秒)和setTimeout()的数组

时间:2016-04-26 15:13:16

标签: javascript

我有这段代码:

times.forEach(function(element) {
    setTimeout(function() { alert(element); }, element * 1000); 
});

和这个数组:[1, 5, 1]

我预计会有一个警报,首先是1秒后,然后是第一个之后的另一个警报,第二个之后是1秒后的最后一个警报,但是与1的相关的警报在开始时一起显示...有什么帮助吗?

5 个答案:

答案 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秒后发出警报,
  • 从现在起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或其他一些东西来获得干净的代码:

&#13;
&#13;
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;
&#13;
&#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);
});