Javascript 在推送数据之前等待数组元素存在

Javascript 在推送数据之前等待数组元素存在,javascript,Javascript,我有一个对象数组,如下所示: var arr = [{ 'timestamp' : 1, },{ 'timestamp' : 2, },{ 'timestamp' : 3, },{ ... }]; arr[data.timestamp].someProperty = "something" 其中,我使用计时器功能生成新对象并将其推送到arr: this.state.labelTimer = window.setInterval(function () { addObjectToAr

我有一个对象数组,如下所示:

var arr = [{
'timestamp' : 1,
},{
'timestamp' : 2,
},{
'timestamp' : 3,
},{
...
}];
arr[data.timestamp].someProperty = "something"
其中,我使用计时器功能生成新对象并将其推送到arr

this.state.labelTimer = window.setInterval(function () {
     addObjectToArr(timeStamp);
}, 1000);
事情变得有点棘手,因为我还有一个WebSocket实现,它使用Laravel Echo修改arr中对象的属性:

// This method gets called whenever the WebSocket receives incoming data

Echo.channel('testChannel')
     // we have detected incoming data
    .listen('dataTrigger', (e) => {
     // modify the object at some array index
     modifyObjectInArr(e.data);
});
modifyObjectInArr(数据)函数将属性附加到数组中的对象,如下所示:

var arr = [{
'timestamp' : 1,
},{
'timestamp' : 2,
},{
'timestamp' : 3,
},{
...
}];
arr[data.timestamp].someProperty = "something"
值得注意的是,对于同一个时间戳,我可能会有多个请求进入,从而导致如下所示的对象:

var arr= [{
'timestamp' : 1,
'val_1' : 12, // originating from one websocket call
'val_2' : 13 // originating from another websocket call
}];

有时,WebSocket似乎会尝试在arr[data.timestamp]处修改对象,然后通过带有计时器的函数将元素推送到数组中。是否有一种好方法可以等待数组在所需索引处有一个元素(我不能简单地检查它是否已经存在,如果不存在,推送它——在这个特定问题中它必须由计时器生成)然后从WebSocket推送传入数据?

您可以使用延迟实例化模式:

var arr = [];

function getDataFrame(timeStamp) {
  // Gets existing or creates new object
  return arr[timeStamp] || (arr[timeStamp] = { timestamp: timeStamp });
}

function modifyObjectInArr(data) {
   getDataFrame(data.timestamp).someProperty = 'something';
}

this.state.labelTimer = window.setInterval(function () {
  getDataFrame(timeStamp);
}, 1000);

这样,无论间隔回调还是web套接字回调首先尝试操作数据,都没有竞争条件。

您可以使用延迟实例化模式:

var arr = [];

function getDataFrame(timeStamp) {
  // Gets existing or creates new object
  return arr[timeStamp] || (arr[timeStamp] = { timestamp: timeStamp });
}

function modifyObjectInArr(data) {
   getDataFrame(data.timestamp).someProperty = 'something';
}

this.state.labelTimer = window.setInterval(function () {
  getDataFrame(timeStamp);
}, 1000);

这样,无论是间隔回调还是web套接字回调,都不存在争用条件。

我和一位同事构建了一个解决类似问题的工具—在我们的例子中,我们希望等到数组达到特定长度。这主要用于测试(等到我们得到X个事件,然后检查它们)

但它基本上是阵列的替代品:

您可以创建一个“AwaitableArray()”,然后将项目推送到其中并等待长度:

let arr = new AwaitableArray();

setInterval(() => arr.push("test"), 500);

// This waits until 2 items have been pushed to the array.
await arr.untilLength(2);
因此,您可以创建这个可等待的数组,而不是常规数组,并等待该索引被命中

这是一款非常基本的atm机,不支持pop,只需等待向上推到该索引,但您可以非常轻松地扩展它,以完成您需要的任何操作:


它只是使用代理来拦截请求——我对在高流量环境中使用它持谨慎态度——我不知道它可能会对性能产生什么影响——它只是我们的一个测试工具,但我们在这种情况下广泛使用它。

一位同事和我构建了一些解决类似问题的工具——在我们的案例中,我们希望等待阵列达到特定长度。这主要用于测试(等到我们得到X个事件,然后检查它们)

但它基本上是阵列的替代品:

您可以创建一个“AwaitableArray()”,然后将项目推送到其中并等待长度:

let arr = new AwaitableArray();

setInterval(() => arr.push("test"), 500);

// This waits until 2 items have been pushed to the array.
await arr.untilLength(2);
因此,您可以创建这个可等待的数组,而不是常规数组,并等待该索引被命中

这是一款非常基本的atm机,不支持pop,只需等待向上推到该索引,但您可以非常轻松地扩展它,以完成您需要的任何操作:


它只是使用代理来拦截请求——我对在高流量环境中使用它持谨慎态度,我不知道它可能会对性能产生什么影响。它只是我们的一个测试工具,但我们在这种情况下使用它的频率相当高。

更新了原始帖子,让这一点更加清楚——感谢您的介绍将这两个函数合并为1,这样它们就不会有任何计时差异我不太确定是否可以--websocket函数在未知时间触发,我需要计时器以1秒的间隔生成标签,而不管websocket发生了什么,而不是
arr[data.timestamp].someProperty=“something”
尝试
arr[data.timestamp]={someProperty:“something”}
。如果这是传递的唯一数据点,这将起作用,但我将对arr中的特定索引有多个websocket请求;所以其中一个会覆盖另一个。更新了原始帖子以使其更清楚-感谢您将其提出来您应该将2个函数合并为1个,这样它们就不会有任何时间差我不太确定我可以-websocket函数在未知时间触发,我需要计时器在1秒的时间间隔内生成标签,而不管WebSocketin发生了什么,而不是
arr[data.timestamp].someProperty=“something”
try
arr[data.timestamp]={someProperty:“something”}
。如果这是传递的唯一数据点,这将起作用,但是我将有多个websocket请求arr中的特定索引;所以一个会凌驾于另一个之上。