具有多个标签的LocalStorage和SetInterval()

时间:2019-06-28 10:38:08

标签: javascript

我们有一些数据存储在localstorage中,并且我们正在使用window.setInterval()每分钟定期进行更新。在此间隔内,我们将不断读取和写入数据。

由于我们使用SetInterval()可能会发生并发问题,因为多个选项卡可以同时修改本地存储中的数据?


编辑1:详细解释场景:

每个标签都针对某个键(例如localstorage)在"xyz"中写入一些数据,并且正在运行的JavaScript中也存在setInterval(),从而不断检查xyz键数据。如果针对该键存在一些数据,则setInterval callback()将其发送到后端。每个执行相同脚本的选项卡将读取xyz键,并在执行一些逻辑后将一些数据附加到现有值上。

我怀疑是否可能发生并发问题,就像一个选项卡可能正在读取“ xyz”键并将数据添加到本地存储中一样,而另一个选项卡可能同时在做相同的事情。现在两者都将尝试同时发送数据,因此我可能会在后端两次接收相同的数据。

3 个答案:

答案 0 :(得分:0)

  

由于我们使用SetInterval()可能会发生并发问题,因为多个选项卡可以同时修改本地存储中的数据?

这有两个方面:

  1. getItem / setItem(及其访问器等效项)是否是原子的?
  2. 进行getItem / setItem呼叫的系列的不同选项卡/窗口是否可以使这些呼叫交错?

令人惊讶的是,在#1上,storage specification似乎没有正面应对。在“注释”中说:

  

注意

     

此规范不需要上述方法一直等到将数据物理写入磁盘之后。只需保持访问相同键/值对基础列表的不同脚本的一致性即可。

......这向我暗示getItem / setItem将是原子的-也就是说,如果两个线程调用{{1},则您要获取/设置的数据不会被破坏} / getItem同时

关于#2,我认为没有任何保证,不。如果每个选项卡/窗口都有其自己的线程,则理论上这些线程中的两个可以同时输入代码块进行这些更新。有时,标签页/窗口共享一个线程,在这种情况下,您会很安全,但是...

我会避免在setItem中有很多不同的条目需要以协调的方式进行更新。相反,我将使用具有结构的单个条目。我通常为此使用JSON。因此获取数据看起来像这样:

localStorage

并保存如下:

let data = JSON.parse(localStorage.getItem("the-data")) || {/*...default structure here...*/};

所以你可以做

localStorage.setItem("the-data", JSON.stringify(data));

然后您将在线程之间进行简单的竞争(最后一个写入获胜),但是存储的数据将保持一致。

答案 1 :(得分:0)

我认为,这实际上取决于您认为什么是“并发问题”。

就写作而言,我认为您不会遇到任何问题,浏览器可以很好地管理应该何时何地写入localstorage的内容。您的数据在此过程中不会被破坏。

对于阅读而言,我相信当您从Tab1进行读取时会遇到问题,但是最后一次写入是从Tab2中进行的。

答案 2 :(得分:-1)

对于您要实现的目标-网络工作者-会更好,因为它适合您页面的每个标签。