Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/402.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 具有多个选项卡的localstorage和setInterval()_Javascript - Fatal编程技术网

Javascript 具有多个选项卡的localstorage和setInterval()

Javascript 具有多个选项卡的localstorage和setInterval(),javascript,Javascript,我们在localstorage中存储了一些数据,并使用window.setInterval()每分钟定期更新一次。在这段时间内,我们不断地读取和写入数据 由于使用了setInterval(),多个选项卡可以同时修改localstorage中的数据,是否会出现并发问题 编辑1:详细解释场景: 每个选项卡都针对一个键(例如xyz)向localstorage写入一些数据,并且运行的javascript中存在的setInterval(),不断检查xyz键数据。如果键上存在一些数据,则setInterv

我们在
localstorage
中存储了一些数据,并使用
window.setInterval()
每分钟定期更新一次。在这段时间内,我们不断地读取和写入数据

由于使用了
setInterval()
,多个选项卡可以同时修改
localstorage
中的数据,是否会出现并发问题


编辑1:详细解释场景:

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


我怀疑是否会出现并发问题,例如一个选项卡可能正在读取
xyz
键并向本地存储添加数据,而另一个选项卡可能正在同时执行相同的操作。现在两者都将尝试同时发送数据,因此我可能会在后端接收相同的数据2次。

编辑后添加:还有一种可能性,您可以尝试找出您的哪个页面/选项卡处于活动状态(您的页面),然后仅在活动选项卡上激活计时器,从而降低发生并发的可能性。 下面是用于可见性检查的api

由于多个选项卡可以同时修改本地存储中的数据,所以使用SetInterval()可能会出现并发问题吗

这有两个方面:

  • getItem
    /
    setItem
    (及其访问器等价物)是原子的吗
  • 执行一系列
    getItem
    /
    setItem
    调用的不同选项卡/窗口能否将这些调用交错
  • 在#1上,令人惊讶的是,政府似乎没有正面解决这一问题。在一份“说明”中,它说:

    注意

    本规范不要求上述方法等待数据物理写入磁盘。只有访问同一基本键/值对列表的不同脚本的一致性是必需的

    …这对我来说意味着
    getItem
    /
    setItem
    将是原子的-也就是说,如果两个线程同时调用
    getItem
    /
    setItem
    ,那么您获取/设置的数据不会被破坏

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

    我会避免在
    localStorage
    中有大量需要以协调方式更新的不同条目。相反,我会使用一个带有结构的条目。我通常使用JSON来实现这一点。因此,获取数据的过程如下所示:

    let data = JSON.parse(localStorage.getItem("the-data")) || {/*...default structure here...*/};
    
    localStorage.setItem("the-data", JSON.stringify(data));
    
    保存它看起来是这样的:

    let data = JSON.parse(localStorage.getItem("the-data")) || {/*...default structure here...*/};
    
    localStorage.setItem("the-data", JSON.stringify(data));
    
    所以你可以

    let data = JSON.parse(localStorage.getItem("the-data")) || {/*...default structure here...*/};
    // ...modify the various parts of `data`...
    localStorage.setItem("the-data", JSON.stringify(data));
    

    然后在线程之间留下一个简单的竞争(最后一个写WINS),但是存储的数据将是一致的。在我看来,这确实取决于你认为的“并发问题”。

    就编写而言,我不认为您会有任何问题,浏览器会很好地管理应该在何时向
    localstorage
    写入什么内容。在此过程中,您的数据不会被损坏


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

    当然,除了他们无权访问
    localStorage
    。是的,它无权访问它,但您可以在webworker和localStorage之间建立一些代理,这真的取决于您将如何做。编辑为更好的答案谢谢您的回答和建议。因为window.setInterval()是一个asyn函数,它在事件队列中等待,所以不应该存在任何并发问题。原始数据从何而来?来自ajax呼叫?@MisterJojo-这有什么关系?问题是关于读取和写入
    localStorage
    @DeepakKumar-为什么存储由
    setInterval
    回调处理,而不是在进行更改时由选项卡处理?另外,像Thomas一样,我将向您指出事件:如果您有选项卡A、B和C,并且它们都订阅了
    localStorage
    上的
    storage
    (它们来自同一来源),那么当选项卡B(例如)写入
    localStorage
    时,选项卡A和C将接收
    storage
    事件。这似乎与你在做什么有关(但我仍然不明白你在做什么)。谢谢你的回答,我编辑了这个问题以了解更多细节。在这种情况下,浏览器是否为两个不同的选项卡维护了两个回调队列?@DeepakKumar-正如我前面所说,每个窗口/选项卡始终有一个单独的回调队列。问题是是否有一个线程为这些选项卡上的队列提供服务,或者每个选项卡都有自己的线程,在后一种情况下,这意味着什么——我在回答中提到了这一点。我非常同意@t.J.Crowder:D@T.J.Crowder根据这个博客,跨多个选项卡的域将有一个线程,这意味着一个队列@DeepakKumar——正如我在评论和回答中至少说过三次的那样:每个选项卡/窗口都有自己的队列。正如我至少说过两次的:选项卡/窗口可以共享一个线程。然后,该线程必须在为每个队列提供服务之间来回运行。