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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/88.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 浏览器中的cookie读/写是原子的吗_Javascript_Html_Concurrency - Fatal编程技术网

Javascript 浏览器中的cookie读/写是原子的吗

Javascript 浏览器中的cookie读/写是原子的吗,javascript,html,concurrency,Javascript,Html,Concurrency,我正试图实现一个交叉表互斥来满足我的需要。我找到了一个实现。这似乎很有希望。基本上,它实现时需要原子读/写来创建互斥 但是,它依赖于提供原子读/写的本地存储。这在除Chrome之外的大多数浏览器中都能很好地工作 所以我的问题是,我可以使用cookie读/写吗?在所有主流浏览器(如Chrome、Safari、Firefox)中,cookie读/写都是原子的吗?否。即使浏览器可能在cookie上实现读和写锁定,也无法保护您免受读和写之间发生的更改。通过查看,很容易看出这一点,那里没有互斥功能…coo

我正试图实现一个交叉表互斥来满足我的需要。我找到了一个实现。这似乎很有希望。基本上,它实现时需要原子读/写来创建互斥

但是,它依赖于提供原子读/写的本地存储。这在除Chrome之外的大多数浏览器中都能很好地工作


所以我的问题是,我可以使用cookie读/写吗?在所有主流浏览器(如Chrome、Safari、Firefox)中,cookie读/写都是原子的吗?

否。即使浏览器可能在cookie上实现读和写锁定,也无法保护您免受读和写之间发生的更改。通过查看,很容易看出这一点,那里没有互斥功能…

cookies和
localStorage都不提供原子事务

我想你可能误解了那篇博文,它并没有说他的实现在Chrome中不起作用,它不依赖于
localStorage
提供原子读/写。他说,在Chrome中,正常的
localStorage
访问更不稳定。我假设这与Chrome为每个选项卡使用单独的进程有关,而大多数其他浏览器倾向于为所有选项卡使用单个进程。他的代码在
localStorage
之上实现了一个锁定系统,该系统可以防止内容被覆盖


另一个解决办法是使用。IndexedDB不提供原子事务。作为一个新标准,它在浏览器中的支持程度不如
localStorage
,但在最新版本的Firefox、Chrome和IE10中,它确实得到了很好的支持。

我今天在使用localStorage时遇到了这个并发问题(两年后)

场景:浏览器的多个选项卡(例如Chrome)具有相同的脚本代码,基本上是同时执行的(例如由Signal调用)。代码读取和写入本地存储。由于选项卡在不同的进程中运行,但会集体访问共享的本地存储,因此读取和写入会导致未定义的结果,因为此处缺少锁定机制。在我的例子中,我希望确保只有一个选项卡可以与本地存储一起工作,而不是所有选项卡

我尝试了上面问题中提到的Benjamin Dumke von der Ehe的锁定机制,但得到了不想要的结果。所以我决定推出自己的实验代码:

本地存储锁:

Object.getPrototypeOf(localStorage).lockRndId = new Date().getTime() + '.' + Math.random();
Object.getPrototypeOf(localStorage).lock = function (lockName, maxHold, callback) {
    var that = this;
    var value = this.getItem(lockName);
    var start = new Date().getTime();    
    var wait = setInterval(function() {
        if ((value == null) || (parseInt(value.split('_')[1]) + maxHold < start)) {
            that.setItem(lockName, that.lockRndId + '_' + start);
            setTimeout(function () {
                if (that.getItem(lockName) == (that.lockRndId + '_' + start)) {
                    clearInterval(wait);
                    try { callback(); }
                    catch (e) { throw 'exeption in user callback'; }
                    finally { localStorage.removeItem(lockName); }
                }
            }, 100);
        }        
    }, 200);        
};
Object.getPrototypeOf(localStorage).lockRndId=new Date().getTime()+'.+Math.random();
Object.getPrototypeOf(localStorage).lock=函数(lockName,maxHold,callback){
var=这个;
var值=this.getItem(lockName);
var start=new Date().getTime();
var wait=setInterval(函数(){
if((value==null)| |(parseInt(value.split(“”“)[1])+maxHold
用法:

Object.getPrototypeOf(localStorage).lockRndId = new Date().getTime() + '.' + Math.random();
Object.getPrototypeOf(localStorage).lock = function (lockName, maxHold, callback) {
    var that = this;
    var value = this.getItem(lockName);
    var start = new Date().getTime();    
    var wait = setInterval(function() {
        if ((value == null) || (parseInt(value.split('_')[1]) + maxHold < start)) {
            that.setItem(lockName, that.lockRndId + '_' + start);
            setTimeout(function () {
                if (that.getItem(lockName) == (that.lockRndId + '_' + start)) {
                    clearInterval(wait);
                    try { callback(); }
                    catch (e) { throw 'exeption in user callback'; }
                    finally { localStorage.removeItem(lockName); }
                }
            }, 100);
        }        
    }, 200);        
};
lock(lockName、maxHold、callback)

  • lockName-锁字符串的全局作用域唯一名称
  • maxHold-保护脚本的最长时间(毫秒)-整数
  • 回调-包含受保护脚本的函数
示例:“仅在一个选项卡中播放声音”

//var msgSound=新音频('/sounds/message.mp3');
lock('lock1',5000,function()){
//一次只有一个选项卡/浏览器进程到达此处
log('lock aquired:'+new Date().getTime());
//在这里使用getItem、setItem处理本地存储
//例如,只有一个标签应该播放声音,并且只有在3秒内没有人播放的情况下
var tm=new Date().getTime();

if((localStorage.lastMsgBeep==null)||(localStorage.lastMsgBeep非常有必要使用Cookie?因为localStorage现在在有关IndexedDB的chromeNice提示中非常有效。我不认为这篇博文被误解了。Chrome和Opera表现出的问题最多,因为有多个进程/线程可以访问相同的localStorage参数。而每次读或写操作都是无效的mic读-测试-修改-写入序列不能保证不间断。通常在JavaScript中,您不必担心代码被抢占,但是由于本地存储在多个进程/线程之间共享,因此不能依赖这种典型的JavaScript行为。博客中描述的实现就是为了解决这一问题ue.请注意,对于
localStorage
,单次写入是原子的。请参阅(“setItem()和removItem()方法在失败时必须是原子的。在失败的情况下,该方法不会执行任何操作。”)。如果我同时(或快速)在10个单独的选项卡中打开同一URL,这对我不起作用,最终数字在localStorage中只存储了3到4次(运行storeAnotherNumber函数,因此在本例中,结果如下:42,42,42,42)