2 setInterval以不同的间隔修改同一数组

时间:2019-03-21 10:56:00

标签: node.js socket.io data-integrity

如果我创建一个第一个setInterval,它每隔1毫秒推送一次数组中的一个项目,然后又有另一个setInterval(每隔一秒钟)将其复制并重置(原始数组)。

我确定我不会擦除数据吗?因为第一个间隔每隔1毫秒写入一次,而第二个间隔每隔一秒钟重置一次数组?

这是一个jsfiddle http://jsfiddle.net/t1d20usr/

var data = [];

var i = 0;
var interval = setInterval(function() {

  data.push(i);
  i++;

  if(i== 10000) {
    clearInterval(interval);
  }

}, 1);

setInterval(function() {

  var recentData = data;
  //i want to be sure that this will not erase something set between the set of recentData and the reset of this array 
  data = [];   

  $('.container').append(recentData.join(',')');

}, 1000);

它很好用,但是由于逻辑,我想知道有时候我是否会丢失数据。

我为什么要这样做?因为我收到来自不同客户端的许多请求(套接字发出),并且我只想每秒将其请求广播给其他客户端一次,而不是广播每个客户端发出的过大杀伤力。这类似于多人游戏服务器的工作方式。 (我的jsfiddle和interval是模拟请求的示例,我不是那样做的!最终,我将以不同的间隔发射信号,并每隔30ms或大约30ms广播一次)

2 个答案:

答案 0 :(得分:0)

这很可靠。为什么? Javascript是单线程的。每个间隔功能都会在下一个间隔功能开始运行之前完成。

您可能考虑将其视为一个队列。您的1ms间隔函数将元素放入队列,而您的1s函数则将所有排队的元素一次性移出队列。

您将data数组替换为空数组的技术效果很好。这样就不会有任何重复。

如果您想消费data数组中的一项,则可以使用

   const item = data.length > 0 ? data.shift() : null

但是这对数组的元素做了很多改组。使用您喜欢的搜索引擎查找性能更高的队列实现。

答案 1 :(得分:0)

该代码是安全的。正如O. Jones所说,javascript的单线程性质将确保您不会丢失数组中的任何元素。

但是我想补充一点:不要期望当达到1s间隔时,数据长度为1000(1s = 1000ms)。数据数组的长度将始终不同,并且通常远小于1000。 特别是在压力下(1ms的时间间隔有点压力),javascript无法处理小于1ms的时间。

查看this的小提琴的修改版本。 在我的机器上,这记录的是每1秒推送248/253个元素的长度。

var data = [];

var i = 0;
var interval = setInterval(function() {

  data.push(i);
  i++;

  if(i== 10000) {
    clearInterval(interval);
  }

}, 1);

setInterval(function() {
  console.log(data.length)
  var recentData = data;
  data = [];

  $('.container').append(recentData.join(',') + '<span class="iteration">/</span>');

}, 1000);