HTML LocalStorage 中的数据在其他窗口/选项卡中可用所需的时间

Mar*_* A. 5 html delay propagation local-storage

我有一个使用 HTML LocalStorage 的网页。同时打开此页面的多个选项卡/窗口是很常见的。由于这些都使用相同的 LocalStorage 并且 LocalStorage 不提供事务或类似功能,因此我想实现某种形式的互斥,以防止不同的选项卡/窗口以不受控制的方式覆盖彼此的数据。

我尝试通过将Burns/Lynch 互斥算法的测试boolean[] F简单地存储在 LocalStorage 中 来将其移植到浏览器。

在 FireFox 中一切正常,但 Chrome 平均允许大约 1.3 个进程(大多数情况下只有 1 个,有时 2 个,很少甚至 3 个或更多)同时进入临界区,而 Internet Explorer 平均允许 2 个进程(大多数情况下只有 2 个)进入关键部分1、2 或 3,有时甚至更多)。

由于该算法已被证明是正确的,并且我的实现非常简单,而且我已经测试了它的其他情况,我能想到为什么会发生这种情况的唯一原因是在 Chrome 和 IE 中存在延迟在我在一个选项卡/窗口中写入 LocalStorage 时与新值在所有其他选项卡/窗口中可见时之间。

这可能吗?如果是这样,是否有任何文件或对这些延误有任何保证?或者,更好的是,是否有某种“commit”或“flush()”调用可以用来强制更改立即传播?

更新:

我整理了一些jsfiddle来测试往返时间:

// Get ID
var myID;
id = window.localStorage.getItem("id");
if (id==1) { myID = 1;    window.localStorage.setItem("id", 0); }
      else { myID = 0;    window.localStorage.setItem("id", 1); }

// Initialize statistics variables
var lastrun    = (new Date()).getTime();
var totaldelay = 0;
var count      = 0;
var checks     = 0;

document.documentElement.innerHTML = "ID: "+myID;

// Method that checks the round-trip time
function check() {
    window.setTimeout(check, 1); // Keep running
    value = window.localStorage.getItem("state");
    checks++;
    if (value==myID) return;
    window.localStorage.setItem("state", myID);
    now = new Date().getTime();
    totaldelay += now - lastrun;
    count++;
    lastrun = now;
    document.documentElement.innerHTML = "ID: "+myID+"<br/>"+
                                         "Number of checks: "+checks+"<br/>"+
                                         "Number of round-trips: "+count+"<br/>"+
                                         "Checks per round-trip: "+checks/count+"<br/>"+
                                         "Average round-trip time:"+totaldelay/count;
}

// Go!
window.setTimeout(check, 1000);
Run Code Online (Sandbox Code Playgroud)

如果我在两个不同的窗口中运行这个小提琴,我会在打开的第二个窗口中得到以下数字:

// Get ID
var myID;
id = window.localStorage.getItem("id");
if (id==1) { myID = 1;    window.localStorage.setItem("id", 0); }
      else { myID = 0;    window.localStorage.setItem("id", 1); }

// Initialize statistics variables
var lastrun    = (new Date()).getTime();
var totaldelay = 0;
var count      = 0;
var checks     = 0;

document.documentElement.innerHTML = "ID: "+myID;

// Method that checks the round-trip time
function check() {
    window.setTimeout(check, 1); // Keep running
    value = window.localStorage.getItem("state");
    checks++;
    if (value==myID) return;
    window.localStorage.setItem("state", myID);
    now = new Date().getTime();
    totaldelay += now - lastrun;
    count++;
    lastrun = now;
    document.documentElement.innerHTML = "ID: "+myID+"<br/>"+
                                         "Number of checks: "+checks+"<br/>"+
                                         "Number of round-trips: "+count+"<br/>"+
                                         "Checks per round-trip: "+checks/count+"<br/>"+
                                         "Average round-trip time:"+totaldelay/count;
}

// Go!
window.setTimeout(check, 1000);
Run Code Online (Sandbox Code Playgroud)

Mar*_* A. 3

结果 Internet Explorer 再次赢得了有史以来最差软件的竞争......

实际上 IE11 中存在一个严重的错误(我也看到了 IE10 的问题),如果用户打开多个选项卡,则基本上无法可靠地使用 LocalStorage:每个选项卡本质上都会获得同一存储位置的自己的缓存版本,并且该缓存和实际存储之间的同步充其量是不稳定的(如果发生的话)。人们根本不能依赖将数据发送到另一个选项卡/窗口,基本上永远不能。

这是官方错误报告:IE 11 - 本地存储 - 同步问题

(当然,这只是IE 中 LocalStorage 支持的众多其他问题之一)

我很喜欢这个问题在 2013 年提出的方式,甚至得到了承认,但仍然没有得到解决......

不幸的是,在我的测试中,发布的三个解决方法都没有使事情变得更好。

换句话说:使用LocalStorage进行跨标签/窗口通信在IE10/11中基本上是不可能的。

令人惊讶的是,跨窗口/选项卡的 cookie 同步似乎稳定得多(至少在我使用 IE10 进行的测试中)。所以也许这可以用作解决方法。