JavaScript高级程序设计(4)
第20章 JavaScript API
### 20.1 Atomics与SharedArrayBuffer 609 > 用于保护代码在多线程内存访问模式下不发生资源争用。 ### 20.2 跨上下文消息 616 > 支持从不同源跨文档发送消息,同时保证安全和遵循同源策略 > postMessage()方法:把数据传送到另一个位置,接收 3 个参数:消息、表示目标接收源的字符串和可选的可传输对象的数组。 > > ```javascript > //最后一行代码尝试向内嵌窗格中发送一条消息 > let iframeWindow = document.getElementById("myframe").contentWindow; > iframeWindow.postMessage("A secret", "http://www.wrox.com"); > > //接收到 XDM 消息后,window 对象上会触发 message 事件。 > window.addEventListener("message", (event) => { > // 确保来自预期发送者 > if (event.origin == "http://www.wrox.com") { > // 对数据进行一些处理 > processMessage(event.data); > // 可选:向来源窗口发送一条消息 > event.source.postMessage("Received!", "http://p2p.wrox.com"); > } > }); > ``` ### 20.3 Encoding API 617 > 用于实现字符串与缓冲区之间的无缝转换(越来越常见的操作)。 > > TextEncoder、TextEncoderStream、TextDecoder 和 TextDecoderStream。 ### 20.4 File API与Blob API 622 > 提供了发送、接收和读取大型二进制对象的可靠工具。 ### 20.5 媒体元素 627 >媒体元素<audio>和<video>拥有自己的 API,用于操作音频和视频。并不是每个浏览器都会支持所有媒体格式,使用 canPlayType()方法可以检测浏览器支持情况。 ### 20.6 原生拖放 631 >拖放 API 支持方便地将元素标识为可拖动,并在操作系统完成放置时给出回应。可以利用它创建自定义可拖动元素和放置目标。 ### 20.7 Notifications API 635 > 提供了一种浏览器中立的方式,以此向用户展示消通知弹层。 ### 20.8 Page Visibility API 636 > 为开发者提供页面对用户是否可见的信息。 ### 20.9 Streams API 637 > Streams API 是为了解决一个简单但又基础的问题而生的:Web 应用如何消费有序的小信息块而不是大块信息?这种能力主要有两种应用场景:大块数据可能不会一次性都可用、大块数据可能需要分小部分处理。 ##### 20.9.1 理解流 - > - 三种流: > - 可读流:可以通过某个公共接口读取数据块的流。数据在内部从底层源进入流,然后由消费者(consumer)进行处理。 > - 可写流:可以通过某个公共接口写入数据块的流。生产者(producer)将数据写入流,数据在内部传入底层数据槽(sink)。 > - 转换流:由两种流组成,可写流用于接收数据(可写端),可读流用于输出数据(可读端)。这两个流之间是转换程序(transformer),可以根据需要检查和修改流内容。 > > - 块、内部队列和反压 > > - 流的基本单位是块(chunk)。块可是任意数据类型,但通常是定型数组。每个块都是离散的流片段,可以作为一个整体来处理。 > > - 所有流都会为已进入流但尚未离开流的块提供一个内部队列。 > > - 如果块入列速度快于出列速度,则内部队列会不断增大。流不能允许其内部队列无限增大,因此它会使用反压(backpressure)通知流入口停止发送数据,直到队列大小降到某个既定的阈值之下。这个阈值由排列策略决定,这个策略定义了内部队列可以占用的最大内存,即高水位线(high water mark) ##### 20.9.2 可读流 - > 可读流是对底层数据源的封装。底层数据源可以将数据填充到流中,允许消费者通过流的公共接口读取数据。 > > 1. **ReadableStreamDefaultController** > > ```javascript > // 生成器: 每1000毫秒生成一个递增的整数 > async function* ints() { > for (let i = 0; i < 5; ++i) { > yield await new Promise((resolve) => setTimeout(resolve, 1000, i)); > } > } > //这个生成器的值可以通过可读流的控制器传入可读流。访问这个控制器最简单的方式就是创建ReadableStream 的一个实例,并在这个构造函数的 underlyingSource 参数(第一个参数)中定义start()方法,然后在这个方法中使用作为参数传入的 controller。默认情况下,这个控制器参数是ReadableStreamDefaultController 的一个实例: > const readableStream = new ReadableStream({ > async start(controller) { > for await (let chunk of ints()) { > //调用控制器的 enqueue()方法可以把值传入控制器 > controller.enqueue(chunk); > } > //所有值都传完之后,调用 close()关闭流 > controller.close(); > } > }); > ``` > > 2. **ReadableStreamDefaultReader** > > ```javascript > // ReadableStreamDefaultReader实例可以把流从队列中读出来,该实例可以通过流的 getReader()方法获取。调用这个方法会获得流的锁,保证只有这个读取器可以从流中读取值: > console.log(readableStream.locked); // false > const readableStreamDefaultReader = readableStream.getReader(); > console.log(readableStream.locked); // true > > // 消费者使用这个读取器实例的 read()方法可以读出值: > (async function() { > while(true) { > const { done, value } = await readableStreamDefaultReader.read(); > if (done) { > break; > } else { > console.log(value); > } > } > })(); > // 0 > // 1 > // 2 > // 3 > // 4 > ``` ##### 20.9.3 可写流 - > 可写流是底层数据槽的封装。底层数据槽处理通过流的公共接口写入的数据。 > > 1. 创建 **WritableStream** > 2. **WritableStreamDefaultWriter** > > ```javascript > // 每 1000 毫秒生成一个递增的整数 > async function* ints() { > for (let i = 0; i < 5; ++i) { > yield await new Promise((resolve) => setTimeout(resolve, 1000, i)); > } > } > > //这些值通过可写流的公共接口可以写入流。在传给 WritableStream 构造函数的 underlyingSink参数中,通过实现 write()方法可以获得写入的数据: > const writableStream = new WritableStream({ > write(value) { > console.log(value); > } > }); > > //要把获得的数据写入流,可以通过流的 getWriter()方法获取 WritableStreamDefaultWriter的实例。这样会获得流的锁,确保只有一个写入器可以向流中写入数据: > console.log(writableStream.locked); // false > const writableStreamDefaultWriter = writableStream.getWriter(); > console.log(writableStream.locked); // true > > // 生产者 > (async function() { > for await (let chunk of ints()) { > await writableStreamDefaultWriter.ready; > //写入数据 > writableStreamDefaultWriter.write(chunk); > } > //将流关闭 > writableStreamDefaultWriter.close(); > })(); > ``` ##### 20.9.4 转换流 - > 转换流用于组合可读流和可写流。数据块在两个流之间的转换是通过 transform()方法完成的。 > > ```javascript > // 每 1000 毫秒生成一个递增的整数 > async function* ints() { > for (let i = 0; i < 5; ++i) { > yield await new Promise((resolve) => setTimeout(resolve, 1000, i)); > } > } > //下面的代码创建了一个 TransformStream 的实例,通过 transform()方法将每个值翻倍: > const { writable, readable } = new TransformStream({ > transform(chunk, controller) { > controller.enqueue(chunk * 2); > } > }); > //向转换流的组件流(可读流和可写流)传入数据和从中获取数据,与本章前面介绍的方法相同: > // 消费者 > (async function() { > while (true) { > const { done, value } = await readableStreamDefaultReader.read(); > if (done) { > break; > } else { > console.log(value); > } > } > })(); > // 生产者 > (async function() { > for await (let chunk of ints()) { > await writableStreamDefaultWriter.ready; > writableStreamDefaultWriter.write(chunk); > } > writableStreamDefaultWriter.close(); > })(); > ``` ##### 20.9.5 通过管道连接流 - > 流可以通过管道连接成一串。最常见的用例是使用 pipeThrough()方法把 ReadableStream 接入TransformStream。另外,使用 pipeTo()方法也可以将 ReadableStream 连接到 WritableStream。整个过程与使用 pipeThrough()类似。 ### 20.10 计时API 644 > 提供了一组度量数据进出浏览器时间的可靠工具。 ##### 20.10.1 High Resolution Time API - > Date.now():毫秒级精度。 > > performance.now():微秒级精度。这个方法可以保证时间戳单调增长。 ##### 20.10.2 Performance Timeline API - > 使用一套用于度量客户端延迟的工具扩展了 Performance 接口。性能度量将会采用计算结束与开始时间差的形式。 ### 20.11 Web组件 648 > 为元素重用和封装技术向前迈进提供了有力支撑。 ### 20.12 Web Cryptography API 663 > 让生成随机数、加密和签名消息成为一类特性。
顶部
收展
底部
[TOC]
目录
第1章 JavaScript简介
第2章 在 HTML中使用JavaScript
第3章 语言基础(1)语法变量
第3章 语言基础(2)数据类型
第3章 语言基础(3)操作符
第3章 语言基础(4)语句
第4章 变量、作用域与内存
第5章 基本引用类型
第6章 集合引用类型
第7章 迭代器与生成器
第8 章对象、类与面向对象编程
第9章 代理与反射
第10章 函数
第11章 期约与异步函数
第12章 BOM
第13章 客户端检测
第14章 DOM
第15章 DOM 扩展
第16章 DOM2 和 DOM3
第17章 事件
第18章 动画与 Canvas 图形
第19章 表单脚本
第20章 JavaScript API
第21章 错误处理与调试
第22章 处理 XML
第23章 JSON
第24章 网络请求与远程资源
第25章 客户端存储
第26章 模块
第27章 工作者线程
第28章 最佳实践
相关推荐
WebSocket