浏览器的“ localStorage.generator ++”运算符是原子的吗?

时间:2019-09-11 21:55:21

标签: javascript local-storage

我想实现一个由浏览器本地存储支持的唯一ID生成器。我担心的是,存储DOM对象的++运算符未实现为原子运行。

考虑:

function generateUniqueID() {
  if(!localStorage.generator) {
    localStorage.generator = 0;
  }
  return localStorage.generator++;
}

如果此代码可以在没有任何并发​​问题的情况下运行并在多个浏览器选项卡上生成唯一的ID,从而震撼了此generateUniqueID函数,人们是否可以发表评论?

1 个答案:

答案 0 :(得分:2)

根据W3C Web存储建议(请参阅here),第4.5节“线程”:

  

由于使用了存储互斥锁,多个浏览上下文将能够以脚本无法检测到任何并发脚本执行的方式同时访问本地存储区域。

     

因此,存储对象的长度属性以及该对象的各种属性的值不能在脚本执行期间更改,除非以脚本本身可以预测的方式更改。

对我而言,这意味着互斥体位于对localStorage的脚本的首次访问(读取或写入)上,并且一直保留到该事件循环条目执行返回为止。 实际上,我们在执行链的有效期内拥有对localStorage的独占访问权限。

我可以想象,如果使用await/async,它将破坏执行链,并使代码跨多个事件循环条目执行,从而破坏此合同。即使源代码块看起来是单片的。提防。

该问题的答案是:是的,只要浏览器遵守W3C的建议,所讨论的代码即可正确运行。尽管事实是“测试” if(!localStorage.generator)和“增量” localStorage.generator++位于不同的行中,但在大多数其他执行环境中,不能保证自动执行。