【前端缓存】localStorage是同步还是异步的?为什么?

news/2024/5/15 7:48:47

写在开头

点赞 + 收藏 === 学会

首先明确一点,localStorage是同步的

 一、首先为什么会有这样的问题

localStorage 是 Web Storage API 的一部分,它提供了一种存储键值对的机制。localStorage 的数据是持久存储在用户的硬盘上的,而不是内存。这意味着即使用户关闭浏览器或电脑,localStorage 中的数据也不会丢失,除非主动清除浏览器缓存或者使用代码删除。

当你通过 JavaScript 访问 localStorage 时,浏览器会从硬盘中读取数据或向硬盘写入数据。然而,在读写操作期间,数据可能会被暂时存放在内存中,以提高处理速度。但主要的特点是它的持久性,以及它不依赖于会话的持续性。

 二、硬盘不是io设备吗?io读取不都是异步的吗?

是的,硬盘确实是一个 IO 设备,而大部分与硬盘相关的操作系统级IO操作确实是异步进行的,以避免阻塞进程。不过,在 Web 浏览器环境中,localStorage 的API是设计为同步的,即使底层的硬盘读写操作有着IO的特性。

js代码在访问 localStorage 时,浏览器提供的API接口通常会处于js执行线程上下文中直接调用。这意味着尽管硬盘是IO设备,当一个js执行流程访问 localStorage 时,它将同步地等待数据读取或写入完成,该过程中js执行线程会阻塞。

这种同步API设计意味着开发者在操作 localStorage 时不需要考虑回调函数或者Promise等异步处理模式,可以按照同步代码的方式来编写。不过,这也意味着如果涉及较多数据的读写操作时,可能对性能产生负面影响,特别是在主线程上,因为它会阻塞UI的更新和其他js的执行。

 三、完整操作流程

localStorage 实现同步存储的方式就是阻塞 JavaScript 的执行,直到数据的读取或者写入操作完成。这种同步操作的实现可以简单概述如下:

  1. js线程调用: 当 JavaScript 代码执行一个 localStorage 的操作,比如 localStorage.getItem('key') 或 localStorage.setItem('key', 'value'),这个调用发生在 js 的单个线程上。
  2. 浏览器引擎处理: 浏览器的 js 引擎接收到调用请求后,会向浏览器的存储子系统发出同步IO请求。此时 js 引擎等待IO操作的完成。
  3. 文件系统的同步IO: 浏览器存储子系统对硬盘执行实际的存储或检索操作。尽管操作系统层面可能对文件访问进行缓存或优化,但从浏览器的角度看,它会进行一个同步的文件系统操作,直到这个操作返回结果。
  4. 操作完成返回: 一旦IO操作完成,数据要么被写入硬盘,要么被从硬盘读取出来,浏览器存储子系统会将结果返回给 js 引擎。
  5. JavaScript线程继续执行: js 引擎在接收到操作完成的信号后,才会继续执行下一条 js 代码。

在同步的 localStorage 操作期间,由于 js 的单线程性质,整个线程会阻塞,即不会执行其他任何js代码,也不会进行任何渲染操作,直到 localStorage 调用返回。

 四、localStorage限制容量都是因为同步会阻塞的原因吗?

  1. 资源公平分享:同一用户可能会访问大量不同的网站,如果没有限制,随着时间的积累,每个网站可能会消耗大量的本地存储资源。这样会导致本地存储空间被少数几个站点占用,影响到用户访问其他网页的体验。限制大小可以确保所有网站都有公平的存储机会。
  2. 防止滥用:如果没有存储限制,网站可能会滥用 localStorage,存储大量数据在用户的设备上,这可能导致设备存储空间迅速耗尽,也可能侵犯用户的隐私。
  3. 性能限制:如之前提到的,localStorage 的操作是阻塞的。如果网站能够存储大量数据,就会加剧读写操作对页面性能的影响。
  4. 存储效率:localStorage 存储的是字符串形式的数据,不是为存储大量或结构化数据设计的。当尝试存储过多数据时,效率会降低。
  5. 历史和兼容性:5MB 的限制很早就已经被大多数浏览器实现,并被作为一个非正式的标准被采纳。尽管现在有些浏览器支持更大的 localStorage,但出于跨浏览器兼容性的考虑,开发者通常会假设这个限制。
  6. 浏览器政策:浏览器厂商可能会依据自己的政策来设定限制,可能是出于提供用户更一致体验的角度,或者是出于管理用户数据的方便。

 五、那indexDB会造成滥用吗?

虽然它们提供了更大的存储空间和更丰富的功能,但确实潜在地也可能被滥用。但是与相比 localStorage 增加了一些特性用来降低被滥用的风险:

  1. 异步操作:IndexedDB 是一个异步API,即使它被用来处理更大量的数据,也不会像 localStorage 那样阻塞主线程,从而避免了对页面响应性的直接影响。
  2. 用户提示和权限:对于某些浏览器,当网站尝试存储大量数据时,浏览器可能会弹出提示,要求用户授权。这意味着用户有机会拒绝超出合理范围的存储请求。
  3. 存储配额和限制:尽管 IndexedDB 提供的存储容量比 localStorage 大得多,但它也不是无限的。浏览器会为 IndexedDB 设定一定的存储配额,这个配额可能基于可用磁盘空间的一个百分比或者是一个事先设定的限额。配额超出时,浏览器会拒绝更多的存储请求。
  4. 更清晰的存储管理:IndexedDB 的数据库形式允许有组织的存储和更容易的数据管理。用户或开发者可以更容易地查看和清理占用的数据。
  5. 逐渐增加的存储:某些浏览器实现 IndexedDB 存储时,可能会在数据库大小增长到一定阈值时,提示用户是否允许继续存储,而不是一开始就分配一个很大的空间。

 六、一个例子简单测试一下

其实也不用测,平时写的时候你也没用异步的方式写localStorage吧,我们这里简单写个例子

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><script>const testLocalStorage = () => {console.log("==========> 设置localStorage之前");localStorage.setItem('testLocalStorage', '我是同步的');console.log("==========> 获取localStorage之前");console.log('=========获取localStorage', localStorage.getItem('testLocalStorage'))console.log("==========> 获取localStorage之后");}testLocalStorage()</script>
</body></html>

 写在最后

如果您看到这里了,并且觉得这篇文章对您有所帮助,希望您能够点赞和收藏⭐支持一下作者,感谢!如果文中有任何不准确之处,也欢迎您指正,共同进步。感谢您的阅读,期待您的点赞和收藏⭐!


原文链接:
https://juejin.cn/post/7359405716090011659


http://www.mrgr.cn/p/06717672

相关文章

新装电脑Flutter环境部署坑汇总(持续更新)

1.本地安装&#xff0c;安装fvm的坑 本人电脑使用windows &#xff0c;安装fvm则一般使用choco安装&#xff0c;那么首先需要安装choco,打开powershell/或者cmd运行以下命令&#xff1a; Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager…

C#设计树形程序界面的方法:创建特殊窗体

目录 1.TreeView控件 2.实例 &#xff08;1&#xff09;Resources.Designer.cs &#xff08;2&#xff09;Form1.Designer.cs &#xff08;3&#xff09;Form1.cs &#xff08;4&#xff09;生成效果 以树形来显示程序的菜单&#xff0c;可以更直观、更快捷地对窗体进行…

Kafka 3.x.x 入门到精通(02)——对标尚硅谷Kafka教程

Kafka 3.x.x 入门到精通&#xff08;02&#xff09;——对标尚硅谷Kafka教程 2. Kafka基础2.1 集群部署2.1.1 解压文件2.1.2 安装ZooKeeper2.1.3 安装Kafka2.1.4 封装启动脚本 2.2 集群启动2.2.1 相关概念2.2.1.1 代理&#xff1a;Broker2.2.1.2 控制器&#xff1a;Controller …

【论文阅读】互连网络的负载平衡路由算法 (RLB RLBth)

前言Oblivious Load Balancing 不经意路由负载平衡 1. oblivious routing 不经意/无关路由的背景知识 1. oblivious routing, adaptive routing & minimal/non-minimal routing algorithms 2. RLB and RLBth 1. Motivation of Balancing load 平衡负载的动机2. 一维 ring 的…

【论文阅读】ViTAE:Vision transformer advanced by exploring intrinsic inductive bias

ViTAE:Vision transformer advanced by exploring intrinsic inductive bias 论文地址摘要&#xff1a;简介&#xff1a;3 方法论3.1 重温视觉变压器3.2 ViTAE3.3 缩减单元3.4 Normal cell3.5 模型细节 4 训练4.1 Implementation details4.2 Comparison with the state-of-the-…

Python高阶--闭包

闭包作用:可以用来在一个函数与一组私有变量之间创建关联关系,在给定函数被多次调用的过程中,这些私有变量能够保持其持久性(保存运行环境与变量的状态) 闭包的特征:1.必须要有函数的嵌套,而且外层函数必须返回内层函数。外层函数相当于给内层函数提供了一个包装起来的运…

实验五 Spark SQL编程初级实践

Spark SQL编程初级实践 Spark SQL基本操作 将下列JSON格式数据复制到Linux系统中&#xff0c;并保存命名为employee.json。 { "id":1 , "name":" Ella" , "age":36 } { "id":2, "name":"Bob","a…

数据结构和算法:贪心

贪心算法 贪心算法是一种常见的解决优化问题的算法&#xff0c;其基本思想是在问题的每个决策阶段&#xff0c;都选择当前看起来最优的选择&#xff0c;即贪心地做出局部最优的决策&#xff0c;以期获得全局最优解。 贪心算法和动态规划都常用于解决优化问题。它们之间存在一…

【数据结构】最小生成树(Prim算法、Kruskal算法)解析+完整代码

5.1 最小生成树 定义 对一个带权连通无向图 G ( V , E ) G(V,E) G(V,E)&#xff0c;生成树不同&#xff0c;每棵树的权&#xff08;即树中所有边上的权值之和&#xff09;也可能不同。 设R为G的所有生成树的集合&#xff0c;若T为R中边的权值之和最小的生成树&#xff0c;则T称…

使用大卫的k8s监控面板(k8s+prometheus+grafana)

问题 书接上回&#xff0c;对EKS&#xff08;AWS云k8s&#xff09;启用AMP&#xff08;AWS云Prometheus&#xff09;监控AMG(AWS云 grafana)&#xff0c;上次我们只是配通了EKSAMPAMG的监控路径。这次使用一位大卫老师的grafana的面板&#xff0c;具体地址如下&#xff1a; ht…

【idea】idea 中 git 分支多个提交合并一个提交到新的分支

一、方法原理讲解 我们在 dev 分支对不同的代码文件做了多次提交。现在我们想要把这些提交都合并到 test 分支。首先我们要明白四个 git 操作&#xff0c; commit&#xff1a;命令用于将你的代码变更保存到本地代码仓库中&#xff0c;它创建了一个新的提交&#xff08;commit…

干货整理:好用的文件加密软件有哪些

说到文件加密&#xff0c;想必大家都很熟悉&#xff0c;文件加密已经普遍应用&#xff0c;文件加密是一种重要的安全措施&#xff0c;可以确保数据的机密性、完整性和可用性&#xff0c;降低因数据泄露或丢失带来的风险。 下面小编给大家分享几款常用的加密软件&#xff0c;大…

Spark和Hadoop的安装

实验内容和要求 1&#xff0e;安装Hadoop和Spark 进入Linux系统&#xff0c;完成Hadoop伪分布式模式的安装。完成Hadoop的安装以后&#xff0c;再安装Spark&#xff08;Local模式&#xff09;。 2&#xff0e;HDFS常用操作 使用hadoop用户名登录进入Linux系统&#xff0c;启动…

【Flink入门修炼】2-3 Flink Checkpoint 原理机制

如果让你来做一个有状态流式应用的故障恢复&#xff0c;你会如何来做呢&#xff1f; 单机和多机会遇到什么不同的问题&#xff1f; Flink Checkpoint 是做什么用的&#xff1f;原理是什么&#xff1f; 一、什么是 Checkpoint&#xff1f; Checkpoint 是对当前运行状态的完整记…

IDM下载器_Internet Download Manager 6.42.7

网盘下载 IDM下载器是一款针对互联网所打造的下载管理器。IDM下载器能将下载速度提高5倍&#xff0c;恢复因丢失的连接&#xff0c;网络问题&#xff0c;计算机关闭或意外断电而重新启动中断或中断的下载。IDM下载器还可支持所有流行的浏览器&#xff0c;以使用独特的“高级浏…

论文解读:(VPT)Visual Prompt Tuning

文章汇总 要解决的问题 大型模型应用于下游任务本身就存在挑战。最明显的(通常也是最有效的)适应策略是对预先训练好的模型进行全面的端到端微调。 动机 只微调参数的一个子集 解决的办法 只在输入空间中引入少量特定于任务的可学习参数&#xff0c;而在下游训练期间冻结…

03-JAVA设计模式-策略模式

策略模式 什么是策略模式 策略模式&#xff08;Strategy Pattern&#xff09;是行为设计模式之一&#xff0c;它使你能在运行时改变对象的行为。在策略模式中&#xff0c;一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为模式。 在策略模式中&#xff0c;…

Matlab 使用subplot绘制多个子图,一元拟合

实现效果&#xff1a; clc; clear;filename sri.xlsx; % 确认文件路径data readtable(filename); datavalue data{:,2:end}; datavalue datavalue;fig figure(Position, [0, 0, 1500, 900]); indexString ["(a)","(b)","(c)","(d)&qu…

go语言并发实战——日志收集系统(八) go语言操作etcd以及利用watch实现对键值的监控

有关包的安装 我们要实现go语言对第三方包的操作需要我们下载第三方包go.etcd.io&#xff0c;下载命令&#xff1a; go get go.etcd.io/etcd/client/v3 ectd的put与get操作 相关函数说明与示例 我们想实现对etcd进行简单的操作的步骤还是比较简单的&#xff0c;在我上一篇文…

Spring Boot 如何实现缓存预热

Spring Boot 实现缓存预热 1、使用启动监听事件实现缓存预热。2、使用 PostConstruct 注解实现缓存预热。3、使用 CommandLineRunner 或 ApplicationRunner 实现缓存预热。4、通过实现 InitializingBean 接口&#xff0c;并重写 afterPropertiesSet 方法实现缓存预热。 1、使用…