浏览器、网络与安全 · KNOWLEDGE CHAPTER
K16

本地数据与流式处理

把本地数据与网络数据看作有生命周期的资源:谁拥有这一版数据、何时真正提交、还能不能消费、谁负责取消。存储成功、网络成功和业务同步成功是三种不同事实。

浏览器、网络与安全2 道章节练习5 道主练关联

核心模型

把本地数据与网络数据看作有生命周期的资源:谁拥有这一版数据、何时真正提交、还能不能消费、谁负责取消。存储成功、网络成功和业务同步成功是三种不同事实。

原理与机制

存储选择包含故障与恢复

localStorage 是同步字符串键值,适合少量偏好;sessionStorage 增加标签页会话隔离。较大的结构化草稿、索引查询和离线队列更适合 IndexedDB。容量不是唯一指标,还要比较主线程阻塞、数据迁移与查询方式。配额、隐私模式、存储压力和用户清理都可能影响可用性,持久存储请求也不等于永久保证。重要编辑需要本地修订号、待同步操作与服务端确认版本,收到旧确认不能顺手清空新编辑。

事务具有时间和连接边界

IndexedDB 单次请求 success 不代表整个事务 complete。事务只在规定的事件循环阶段活动,把网络 await 放进读写事务可能使后续操作落在已提交事务之外;应先准备网络数据,再做短而完整的原子本地更新。升级数据库时,旧标签页持有连接会阻塞 versionchange,新页处理 blocked,旧页在适当时机关闭连接。大量数据可先完成必要 schema 变更,再按带版本的迁移游标分批转换,保证中途退出可恢复。

Fetch 的响应不是可重复读取的普通对象

fetch 收到 404、500 通常仍兑现为 Response,因此先检查状态,再按协议解析;204 或 HTML 错误页不能机械调用 json。正文是可消费的流,读取后再 clone 通常已太晚。AbortController 能中止客户端工作,但不是服务端事务回滚。被新查询替代的旧请求,成功、错误和 finally 都需验证本轮归属;只挡旧成功回调,旧 finally 仍可能关闭新请求的 loading。

流与跨页协调都需要有界协议

按块处理能降低峰值内存,前提是不把所有块再堆进数组。解码器负责跨块字符,应用缓冲负责跨块记录,两者不可混淆。tee 或 Response.clone 的快消费者可推动上游,慢分支因而积累数据,需限制用途并取消不用的分支。BroadcastChannel 只通知,不持久、不互斥;Web Locks 可让遵守协议的标签页串行进入临界区,但拿锁后仍须重新读取权威状态,后来的申请并不会自动跳过已做完的任务。

错误路径同样拥有数据归属

可靠应用不仅测试成功下载,还要把存储拒绝、配额耗尽、事务 abort 与网络错误作为可恢复状态呈现。正在同步的修订与继续输入的修订分开记录,界面明确“已保存到本机”和“服务器已确认”,不会把本地完成误报为跨设备可见。流解析也应限制单条记录和残留缓冲长度,故意输入永远不换行的数据验证上限。监控只留必要错误摘要,不能为定位问题无限复制完整响应或私密草稿。

最小示例

javascript
javascript
async function countBytes(url, signal) {
  const response = await fetch(url, { signal });
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  if (!response.body) return 0;
  const reader = response.body.getReader();
  let total = 0;
  try {
    while (true) {
      const { done, value } = await reader.read();
      if (done) return total;
      total += value.byteLength;
    }
  } finally { reader.releaseLock(); }
}

调用方传入 AbortController.signal 并处理拒绝。示例不保存每个块,所以应用层只保留累计数字和当前块;它统计的是交付给脚本的正文块字节,并非证明网络栈没有缓冲。若循环业务处理可能抛错并希望停止未读上游,应额外取消 reader;文本协议还需流式解码与记录缓冲。

环境:支持 Fetch、ReadableStream 与 AbortController 的现代浏览器;调用方提供允许读取的 URL、signal,并处理返回 Promise 的拒绝。

核验:已静态审查示例与本章机制一致;未运行此示例,未进行框架或浏览器集成测试。观察结果为待复现的教学预期。

边界与取舍

边界

  • 本地事务完成不是云端已同步,浏览器没有过期时间也不代表数据不会清除。
  • BroadcastChannel 不能实现只执行一次;Web Locks 只保护约定临界区,跨设备去重仍需服务端。
  • 网络块不是 JSON 记录;clone 的慢分支可能累积整份响应,流式 API 不自动保证低内存。

取舍

  • IndexedDB 支持异步查询与事务,换来升级与错误处理复杂度;少量偏好不必过度建模。
  • 分流便于日志和业务各自消费,但可能放大内存与敏感信息暴露;大响应优先单次解析、有限摘要。

口述示范

我把数据流程拆为获取、消费、本地提交和远端确认。Fetch 成功要继续验证 HTTP 与格式,流要有缓冲上限和取消,IndexedDB 要尊重事务与升级边界。多标签协调需要锁后复核,重要数据最终靠版本和幂等协议保证。

章节练习

练习 1

假设 TranslateFlow 离线草稿两页同时同步,怎样避免重复与误删?

展开检查点
  • 本地操作有稳定 ID、修订号与独立确认状态。
  • 拿 Web Lock 后重读共享状态,完整 await 同步工作。
  • 服务端幂等;旧确认只标记对应操作,不删除后来草稿。
练习 2

大文件下载同时 clone 给日志,内存持续增长;文本记录还偶尔解析失败,解释并修复。

展开检查点
  • 证明慢日志分支积压,改为有限摘要或有界分流。
  • 流式解码中文,保留不完整记录并限制长度。
  • 测试错误状态、取消、空正文、末行无换行及清理。

参考来源与核验边界

以现代浏览器 Web API 为基线;存储分区、配额、持久存储与 Web Locks 可用性须在目标浏览器和嵌入环境核验。

内容版本:2026-10-04.2 · 题目和来源 ID 保持原样,本站不将面经标签解释为企业官方出题或高频保证。