JavaScript基础知识总结 14:学习JavaScript中的File API、Streams API、Web Cryptography API

news2025/1/20 1:53:51

目录

    • 一、Atomics和SharedArrayBuffer
    • 二、原子操作基础
      • 1、算术及位操作方法
      • 2、原子读和写
      • 3、原子交换
      • 4、原子Futex操作与加锁
    • 三、跨上下文消息
    • 四、Encoding API
    • 五、File API和Blob API
      • 1、File类型
      • 2、FileReader类型
      • 3、FileReaderSync类型
      • 4、Blob与部分读取
    • 六、Streams API
      • 1、应用场景
      • 2、理解流
    • 七、Web Cryptography API
    • 八、JavaScript知识体系合集
    • 九、JavaScript思维导图
    • 十、关注公众号哪吒编程,回复1024,获取Java学习资料,还有不定期的送书活动

一、Atomics和SharedArrayBuffer

多个上下文访问SharedArrayBuffer时,如果同时对缓冲区执行操作,就可能出现资源争用问题。Atomics API 通过强制同一时刻只能对缓冲区执行一个操作,可以让多个上下文安全地读写一个SharedArrayBuffer。
原子操作的本质会排斥操作系统或计算机硬件通常会自动执行的优化(比如指令重新排序)。原子操作也让并发访问内存变得不可能,如果应用不当就可能导致程序执行变慢,为此,Atomics API 的设计初衷是在最少但很稳定的原子行为基础上,构建复杂的多线程JavaScript程序。

二、原子操作基础

1、算术及位操作方法

Atomics API 提供了一套简单的方法用于执行就地修改操作。在ECMA规范中,这些方法被定义为AtomicReadModifyWrite操作。在底层,这些方法都会从SharedArrayBuffer中某个位置读取值,然后执行算术和位操作,最后再把计算结果写到相同的位置。这些操作的原子本质意味着上述读取、修改、写回操作会按顺序执行,不会被其它线程中断。

//创建大小为1的缓冲区
let sharedArrayBuffer = new SharedArrayBuffer(1);
//基于缓冲创建Unit8Array
let typedArray = new Unit8Array(sharedArrayBuffer);
//所有ArrayBuffer全部初始化为0
console.log(typedArray);//Unit8Array[0]
//对索引0处的值执行原子加10
Atomics.add(typedArray,0,10);//Unit8Array[10]
//对索引0处的值执行原子减10
Atomics.sub(typedArray,0,10);//Unit8Array[0]

2、原子读和写

浏览器的JavaScript编译器和CPU架构本身都有权限重排指令以提升程序执行效率。正常情况下,JavaScript的单线程环境是可以随时进行这种优化的,但是,多线程中的指令重排可能导致资源争用,而且极难排错。
Atomics API 通过两种主要方式解决这个问题:

  1. 所有原子指令相互之间的顺序永远不会重排。
  2. 使用原子读或原子写保证所有指令都不会相对原子读写重新排序。

除了读写缓冲区的值,Atomics.load()和Atomics.store()还可以构建“代码围栏”。JavaScript引擎保证非原子指令可以相对于load()和store()本地重排,但这个重排不会侵犯原子读写的边界。

const sharedArrayBuffer = new SharedArrayBuffer(4);
const view = new Unit32Array(sharedArrayBuffer);
//执行非原子写
view[0] = 1;
//非原子写可以保证在这个读操作之前完成,因此这里一定会读到1
console.log(Atomics.load(view,0));//1
//执行原子写
Atomics.store(view,0,2);
//非原子读可以保证在原子写完成后发生,这里一定会读到2
console.log(view[0]);//2

3、原子交换

为了保证连续、不间断的先读后写,Atomics API 提供了两种方法:exchange()和compareExchange()。Atomics.exchange()执行简单的交换,以保证其他线程不会中断值得交换。

const sharedArrayBuffer = new SharedArrayBuffer(4);
const view = new Unit32Array(sharedArrayBuffer);
//在索引0处写入10
Atomics.store(view,0,10);
//从索引0处读取值,然后在索引0处写入5
console.log(Atomics.exchange(view,0,5));//10
//从索引0处读取值
console.log(Atomics.load(view,0));//5

在多线程程序中,一个线程可能只希望在上次读取某个值之后没有其他线程修改该值得情况下对共享缓冲区执行写操作。如果这个值没有被修改,这个线程就可以安全地写入更新后的值:如果这个值被修改了,那么执行写操作将会破坏其他线程计算的值。对于这种任务,Atomics API提供了compare-Exchange()方法。这个方法只在目标索引处的值与预期值匹配时才会执行写操作。

4、原子Futex操作与加锁

如果没有某种锁机制,多线程程序就无法支持复杂需求。为此,Atomics API提供了模仿Linux Futex(快速用户空间互斥量,fast user-space mutex)的方法。这些方法本身虽然非常简单,但可以作为更复杂锁机制的基本组件。
所有原子Futex操作只能用于Int32Array视图,而且,只能用在工作线程内部。

三、跨上下文消息

跨文档消息,有时候也称XDM(cross-document messaging),是一种在不同执行上下文(例如不同工作线程或不同源的页面)间传递信息的能力。

四、Encoding API

Encoding API主要用于实现字符串与定型数组之间的转换。

五、File API和Blob API

1、File类型

File API仍然以表单中的文件输入字段为基础,但是增加了直接访问文件信息的能力。HTML5在DOM上为文件输入元素增加了files集合。当用户在文件字段中选择一个或多个文件时,这个files集合中会包含一组File对象,表示被选中的文件,每个File对象都有一些只读属性。

2、FileReader类型

FileReader类型表示一种异步文件读取机制,可以把FileReader想象成类似于XMLHttpRequest,只不过用于从文件系统读取文件,而不是从服务器读取数据。FileReader类型提供了几个读取文件数据的方法。

  1. readAsText(file,encoding);//从文件中读取纯文本内容并保存在result属性中
  2. readAsDataURL(file);//读取文件并将内容的数据URI保存在result属性中
  3. readAsBinaryString(file);//读取文件并将每个字符的二进制数据保存在result属性中
  4. readAsArrayBuffer(file);//读取文件并将文件内容以ArrayBuffer形式保存在result属性中

3、FileReaderSync类型

FileReader类型的同步版本。

4、Blob与部分读取

某些情况下,可能需要读取部分文件而不是整个文件,为此,File对象提供了一个名为slice()的方法。slice()方法接收两个参数:起始字节和尧都区的字节数。这个方法返回一个Blob的实例,而Blob实际上是File的超类。
blob表示二进制大对象,是JavaScript对不可修改二进制数据的封装类型。包含字符串的数组、ArrayBuffers、ArrayBufferViews,甚至其他Blob都可以用来创建blob。Blob构造函数可以接收一个options参数,并在其中指定MIME类型。

六、Streams API

1、应用场景

Streams API 是为了解决一个简单但又很基础的问题而生的:Web应用如何消费有序的小信息块而不是大块信息?这种能力主要有两种应用场景。

  1. 大块数据可能不会一次性都可用。网络请求的响应就是一个典型的例子。网络负载是以连续信息包形式交付的,而流式处理可以让应用在数据一到达就能使用,而不必等到所有数据都加载完毕。
  2. 大块数据可能需要分小部分处理。视频处理、数据压缩、图像编码和JSON解析都是可以分成小部分进行处理,而不必等到所有数据都在内存中再处理的例子。

2、理解流

Streams API定义了三种流:

  1. 可读流:可以通过某个公共接口读取数据块的流。数据在内部从底层源进入流,然后由消费者consumer进行处理。
  2. 可写流:可以通过某个公共接口写入数据块的流。生产者(consumer)将数据写入流,数据在内部传入底层数据槽(sink)。
  3. 转换流:由两种流组成,可写流用于接收数据,可读流用于输出数据。这两个流质检是转换程序(transformer),可以根据需要检查和修改流内容。

七、Web Cryptography API

Web Cryptography API描述了一套密码学工具,规范了JavaScript如何以安全和符合惯例的方式实现加密。这些工具包括生成、使用和应用加密秘钥对,加密和解密信息,以及可靠地生成随机数。
在需要生成随机数时,很多人会使用Math.random()。这个方法在浏览器中是以伪随机数生成器(PRNG,PseudoRandom Number Generator)方式实现的。所谓的伪指的是生成值的过程不是真的随机。PRNG生成的值只是模拟了随机的特性。浏览器的PRNG并未使用真正的随机源,只是对一个内部状态应用了固定的算法。每次调用Math.random(),这个内部状态都会被一个算法修改,而结果会被转换为一个新的随机数。例如,V8引擎使用了一个名为xorshift128+的算法来执行这种修改。
由于算法本身是固定的,其输入只是之前的状态,因此随机数顺序也是确定的。xorshift128+使用128位内部状态,而算法的设计让任何初始状态在重复自身之前都会产生2128-1个伪随机值。这种循环被称为置换循环,而这个循环的长度被称为一个周期。很明显,如果攻击者知道PRNG的内部状态,就可以预测后续生成的伪随机值。如果开发者无意中使用了PRNG生成了私有密钥用于加密,则攻击者就可以利用PRNG的这个特性算出私有密钥。
伪随机数生成器主要用于快速计算出看起来随机的数,不过并不适合用于加密算法,为解决这个问题,密码学安全伪随机数生成器(CSPRNG,Cryptographically Secure PseudoRandom Number Generator),额外增加了一个熵作为输入,例如测试硬件时间或其它无法预计行为的系统特性,虽然速度上不及PRNG,但是生成的值更难预测了,就可以用于加密。
Web Cryptography API引入了CSPRNG,这个CSPRNG可以通过crypto.getRandomValues()在全局Crypto对象上访问。与Math.random()返回一个0到1之间的浮点数不同,getRandomValues()会把随机值写入作为参数传给它的定型数组。定型数组的类不重要,因为底层缓冲区会被随机的二进制位填充。

八、JavaScript知识体系合集

JavaScript看这一篇就够了,简单全面一发入魂
精通JavaScript?关于JavaScript的内存与性能问题,你又了解多少呢?
JavaScript面试题看这一篇就够了,简单全面一发入魂(持续更新 step1)
JavaScript零基础入门 1:JavaScript表格简介
JavaScript零基础入门 2:JavaScript数据类型简介
JavaScript零基础入门 3:javascript运算符有哪些
JavaScript零基础入门 4:javascript对象有哪些
JavaScript零基础入门 5:JavaScript函数详解
JavaScript零基础入门 6:JavaScript数组详解
JavaScript零基础入门 7:JavaScript基础函数
JavaScript零基础入门 8:JavaScript通过document获取节点元素
JavaScript零基础入门 9:JavaScript读取元素的样式
JavaScript零基础入门 10:JavaScript中的正则表达式
JavaScript零基础入门 11:JavaScript实现图片上传并预览
JavaScript零基础入门 12:JavaScript整合JqGrid完整实例
JavaScript零基础入门 13:DOM规范中的MutationObserver接口

九、JavaScript思维导图

在这里插入图片描述

十、关注公众号哪吒编程,回复1024,获取Java学习资料,还有不定期的送书活动

1、Java程序设计
2、极简JAVA
3、Python技术手册
4、区块链教科书
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/408845.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

uniapp和vue组件之间的传值方法(父子传值,兄弟传值,跨级传值,vuex)

前言 在做vue项目或者uniapp开发微信小程序时,经常会用到组件之间传值,因此想总结记录下。 一、父子传值 父向子传递:props子向父传递:通过 events($emit)父组件想调用子组件的方法:通过 thi…

Get请求报错404出现原因及解决办法

ajax中get请求时报404背景环境项目结构问题成因解决办法1解决办法2背景环境 已学习java基础,html,css,js,jquery,bootstrap,layui,maven,servlet和jsp,刚进入spring的学…

前端下载文件的几种方式

前端下载文件的几种方式 前言 实习一个人负责一个管理系统的前端部分。其中,就有前端下载文件的需要。最终采用的是使用axios发送get请求的方式,因为需要携带token。但是,不应该只注重结果,也应该注重过程,不然可能一…

jQuery选择器(二)(基本过滤器,内容过滤器,可见过滤器)

写在前面 jQuery是一个快速、简洁的 JavaScript 框架,是继Prototype之后又一个优秀的 JavaScript 代码库。jQuery的设计宗旨是“WriteLess,DoMore”,即倡导写更少的代码,做 更多的事情。jQuery封装了 JavaScript 常用的功能代码&…

【Vue】具名插槽

要点: 具名插槽:即具有名字的插槽,在默认插槽基础上指定插槽的名字(name " ")。父组件指明放入子组件的哪个插槽 slot "footer",如果是template可以写成 v-slot : footer。 父组件中…

html中关于侧边导航栏和导航栏的编写

侧边导航栏 <style>.box{width: 50px;height: 50px;background-color: #483957;transition: width .5s,background-color .2s;}.box:hover{background-color: #004FCB;width: 200px;cursor: pointer;}.a1{position: fixed;right: 40px;top: 200px;float: right;}</st…

如何搭建一个vue项目(完整步骤)

如何搭建一个vue项目(完整步骤) 一、环境准备 1、安装node.js 下载地址&#xff1a;https://nodejs.org/zh-cn/界面展示 2、检查node.js版本 查看版本的两种方式 1|node -v 2|node -version 出现版本号则说明安装成功&#xff08;最新的以官网为准&#xff09; 3、为了…

vue环境搭建

前言&#xff1a;1、首先安装nodejs2、其次安装vue-cli&#xff0c;配置vue环境变量3、再次安装webpack、webpack-cli一、NodeJs安装 1、nodejs下载地址&#xff1a;https://nodejs.org/ 2、验证是否安装成功&#xff08;安装时已经自动加入到环境变量的path中&#xff09; 以…

Referer和Referrer Policy以及图片防盗链

​ Referer Referer请求头包含了当前请求页面的来源页面的地址&#xff0c;即表示当前页面是通过此来源页面里的链接进入的。服务端一般使用Referer&#xff08;注&#xff1a;正确英语拼写应该是referrer&#xff0c;由于早期HTTP规范的拼写错误&#xff0c;为了保持向后兼容…

html 简单表格制作(看了它足以应对大部分表格)

目录 基础表格 进阶表格 锦上添花表格 bgcolor background align frame元素 基础表格 首先制作一个表格我们要知道一张简单表格就是由二部分组成分别是表头&#xff0c;表身。 下面就是一个简单的表格。 表头就是黑体加粗的内容&#xff0c;表身就是表格主要表达的内容。…

css里面设置按钮(button)让字体居中

题目&#xff1a;设置button中的字体让其居中&#xff0c;不至于溢出(字体下落&#xff0c;重影等问题) 1&#xff0c;抛出问题&#xff0c;如图所示 2&#xff0c;引出我的代码 <view class"loginBtn"><form action"check.jsp" method"get…

带你吃透Servlet技术(二)

个人主页&#xff1a; 几分醉意的CSDN博客_传送门 前言&#xff1a;在上一篇&#xff0c;我们已经初步的了解了 Servlet技术 传送门&#xff0c;接下来我们继续深入学习Servlet。 本文目录&#x1f496;继承HttpServlet实现Servlet程序✨代码实战✨自动生成doGet和doPost方法✨…

猿创征文|如何使用 Element UI? 以登录框为例带你感受一下基础使用

目录 前言 一、安装&#xff08;所有内容&#xff09; 二、按需引入 三、案例演示 1.案前整理 2.代码演示&#xff08;后附源码&#xff09; 3.源码 前言 Element-ui&#xff0c;一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的组件库&#xff0c;提供了配套设计…

el-upload上传文件

el-upload上传文件 前言 公司和学校项目都用到了上传文件的功能&#xff0c;记录一下。 准备 express实现的上传接口 const express require(express); ​ // 文件上传模块 const multiparty require(multiparty) ​ // 提供跨域资源请求 const cors require(cors) ​ …

Idea中使用Tomcat部署并启动Web项目

首先在Idea中选择编辑运行配置&#xff0c;如下图 左上角的“”号&#xff0c;选择Tomcat服务&#xff0c;如下图 自定义服务名称和项目在浏览器的访问路径 配置Tomcat服务器路径&#xff0c;如下图 然后在服务器中部署项目&#xff08;下面的警告提示&#xff1a;Warning: No …

nginx响应码301及访问路径参数丢失之间的关系

nginx响应码301及访问路径参数丢失之间的关系 本文比较长&#xff0c;所以写了一篇比较短的结果导向的文章&#xff0c;换了一下思路&#xff0c;大家可以看一这篇文章&#xff0c;如果感兴趣再来看这篇文章&#xff1a;nginx导致vue设置history模式下的请求丢失参数 背景描述…

Java使用WebStocket实现前后端互发消息

记录一下自己使用WebStocket实现服务器主动发消息的过程和踩得雷。 需求&#xff1a;车牌识别系统识别到车牌后&#xff0c;持续向前端推送车牌信息&#xff0c;直到前端回复收到。 测试需求&#xff1a;新增 客户后&#xff0c;持续向前端推送客户信息&#xff0c;直到前端收…

type=“module“ 你了解,但 type=“importmap“ 你知道吗

新出了一个系列&#xff1a;Vue2与Vue3 技巧小册 有梦想&#xff0c;有干货&#xff0c;微信搜索 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。 本文 GitHub https://github.com/qq449245884/xiaozhi 已收录&#xff0c;有一线大厂面试完整考点、资料以及我的系列文章。 当E…

css的rotate3d实现炫酷的圆环转动动画

1.实现效果 2.实现原理 2.1 rotate3d rotate3d&#xff1a;rotate3d() CSS 函数定义一个变换&#xff0c;它将元素围绕固定轴移动而不使其变形。运动量由指定的角度定义; 如果为正&#xff0c;运动将为顺时针&#xff0c;如果为负&#xff0c;则为逆时针。 语法&#xff1a; …

【面试题】redux及中间件相关面试题解析

1、什么是Redux&#xff1f; Redux就是一个js容器&#xff0c;用于全局的状态管理 2、为什么在React项目中要使用Redux&#xff1f; 因为React本质上就是一个UI库&#xff0c;它是单向数据流的&#xff0c;就是说数据只能从父组件通过props流向子组件&#xff0c;但如果子组…