问题
I have a webpage that uses HTML LocalStorage. It is common to have multiple tabs/windows of this page open at the same time. Since these all use the same LocalStorage and LocalStorage does not provide transactions or similar, I would like to implement some form of mutual exclusion to prevent the different tabs/windows to overwrite each other's data in an uncontrolled manner.
I tried to just port my test of the Burns/Lynch mutual exclusion algorithm to the browser by simply storing the boolean[] F
in LocalStorage.
Things work perfectly in FireFox, but Chrome allows an average of about 1.3 processes (mostly just one, sometimes two and very rarely even 3 or more) into the critical section at the same time, and Internet explorer allows an average of 2 processes (mostly 1, 2, or 3, sometimes even more) in.
Since the algorithm has been proven correct and my implementation is super-trivial and I've tested the heck out of it otherwise, the only reason that I can come up with for why this is happening is that in Chrome and IE there is a delay between when I write to LocalStorage in one tab/window and when the new value will be visible in all other tabs/windows.
Is this possible? If so, is there any documentation or are there any guarantees on these delays? Or, better yet, is there some kind of "commit"- or "flush()"-call that I can use to force the changes to propagate immediately?
UPDATE:
I put together a little jsfiddle to test out the round-trip times:
// 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);
If I run this fiddle in two different windows, I get the following numbers in the second window I opened:
Browser | Checks per round-trip | Average round-trip time
------------------+-----------------------+-------------------------
Firefox 24.3.0 | 1.00 | 6.1 ms
Chrome 46.0.2490 | 1.06 | 5.5 ms
IE 10 | 17.10 | 60.2 ms
回答1:
Turns out Internet Explorer again wins the competition for worst piece of software ever written...
There's actually a severe bug in IE11 (and I'm seeing issues with IE10 also) that basically makes it impossible to use LocalStorage reliably if the user opens more than one tab: Each tab essentially gets its own cached version of the same storage location and the synchronization between that cache and the actual storage is flaky at best (if it happens at all). One cannot at all rely on data making it to the other tab/window, basically ever.
Here's the official bug-report: IE 11 - Local Storage - Synchronization issues
(Which, naturally, is just one of a huge list of other issues with LocalStorage support in IE)
I love how this issue was opened in 2013 and even acknowledged, but still hasn't been fixed...
Unfortunately none of the three work-arounds posted make things any better in my tests.
In other words: Cross-tab/window communication using LocalStorage is basically impossible in IE10/11.
Surprisingly, the synchronization of cookies across windows/tabs seems to be a lot more stable (at least in my tests with IE10). So maybe that can be used as a work-around.
来源:https://stackoverflow.com/questions/33309497/time-it-takes-for-data-in-html-localstorage-to-be-available-in-other-windows-tab