首页 > 其他分享 >js Stream API简单使用

js Stream API简单使用

时间:2024-09-18 11:24:14浏览次数:7  
标签:err console log Stream 分块 js API new const

ReadableStream

<script>
  // TextDecoder将字节转换为字符串,默认 utf-8 编码
  let uint8Array = new Uint8Array([72, 101, 108, 108, 111]);
  console.log(new TextDecoder().decode(uint8Array)); // Hello

  let uint8Array1 = new Uint8Array([228, 189, 160, 229, 165, 189]);
  console.log(new TextDecoder().decode(uint8Array1)); // 你好

  let uint8Array2 = new Uint8Array([0, 72, 101, 108, 108, 111, 0]);
  let binaryString = uint8Array2.subarray(1, -1);
  console.log(new TextDecoder().decode(binaryString)); // Hello

  // TextEncoder将字符串转换为字节
  console.log(new TextEncoder().encode("Hello")); // Uint8Array 72,101,108,108,111

  //ReadableStream 可读取的二进制流
  // 数据被按序读入到许多小的片段,这些片段被称作分块(chunk)。分块可以是单个字节,也可以是某种更大的数据类型,例如特定大小的类型化数组。单个流的分块可以有不同的大小和类型。
  // 已放入到流中的分块称作已入队(enqueued)——这意味着它们已经在队列中排队等待被读取。流的一个内置队列跟踪了那些尚未读取的分块。
  // 流中的分块由一个 reader 读取——该数据处理过程一次只处理一个分块,允许你对其执行任何类型的操作。
  // 每个 reader 都有一个关联的 controller,用来控制流例如可以将流关闭。
  fetch("http://localhost:3000/html-demos/table.html")
    .then((response) => response.body)
    .then((rb) => {
      const reader = rb.getReader();
      return new ReadableStream({
        start(controller) {
          // 处理每一个数据块
          function push() {
            reader.read().then(({ done, value }) => {
              // 读取完全部数据块
              if (done) {
                console.log("done", done);
                controller.close();
                return;
              }

              // 获取数据value,并通过controller发送给浏览器
              controller.enqueue(value);
              console.log(done, value);
              push();
            });
          }

          push();
        },
      });
    })
    .then((stream) =>
      // 处理流数据
      new Response(stream, { headers: { "Content-Type": "text/html" } }).text()
    )
    .then((result) => {
      console.log(result);
    });
</script>

WritableStream

<script> 

  const list = document.querySelector("ul");
  function sendMessage(message, writableStream) {
    const defaultWriter = writableStream.getWriter();
    const encoder = new TextEncoder();
    const encoded = encoder.encode(message, { stream: true });
    encoded.forEach((chunk) => {
      defaultWriter.ready
        .then(() => {
          return defaultWriter.write(chunk);
        })
        .then(() => {
          console.log(chunk, "Chunk written to sink.");
        })
        .catch((err) => {
          console.log("Chunk error:", err);
        });
    });
    // 重新调用ready确保writer关闭前所有数据已写入
    defaultWriter.ready
      .then(() => {
        defaultWriter.close();
      })
      .then(() => {
        console.log("All chunks written");
      })
      .catch((err) => {
        console.log("Stream error:", err);
      });
  }
  const decoder = new TextDecoder("utf-8");
  // CountQueuingStrategy 接口提供了一个内置的、用于对分块进行计数的队列策略,可以在构造流的时候使用。
  const queuingStrategy = new CountQueuingStrategy({ highWaterMark: 1 });
  let result = "";
  // 一个可写流(Writable stream)是一个可以写入数据的数据终点
  const writableStream = new WritableStream(
    {
      write(chunk) {
        return new Promise((resolve, reject) => {
          var buffer = new ArrayBuffer(1);
          var view = new Uint8Array(buffer);
          view[0] = chunk;
          var decoded = decoder.decode(view, { stream: true });
          var listItem = document.createElement("li");
          listItem.textContent = "Chunk decoded: " + decoded;
          list.appendChild(listItem);
          result += decoded;
          resolve();
        });
      },
      close() {
        var listItem = document.createElement("li");
        listItem.textContent = "[MESSAGE RECEIVED] " + result;
        list.appendChild(listItem);
      },
      abort(err) {
        console.log("Sink error:", err);
      },
    },
    queuingStrategy
  );
  sendMessage("Hello, world.", writableStream);
</script>

标签:err,console,log,Stream,分块,js,API,new,const
From: https://www.cnblogs.com/caroline2016/p/18418146

相关文章

  • commonJs和ESModule的区别
    1.规范的区别ESM模块的导入使用Import关键字,导出使用export关键字。commonJs导入使用require关键字,导出使用module.export 2.文件名后缀不一样(这一点不用记,针对Node)在node.js,默认将.js后缀文件识别为CJS模块,.cjs也是CJS模块,.mjs文件识别为esm模块。 3.模块加载时机......
  • Node.js 版本管理工具对比总结
    Node.js版本管理工具用于帮助开发者在不同项目中灵活切换Node.js和npm版本。常见的工具有nvm、n、nvs、fnm和Volta。以下是它们的优缺点、常用命令及对比总结。nvm(NodeVersionManager)优点:支持macOS和Linux。可以灵活地安装、切换和卸载不同版本的Node.js。......
  • 使用 Wake Lock API:保持设备唤醒的最佳实践
    在现代Web应用中,尤其是涉及视频播放、实时通信、地图导航等长时间运行的任务时,用户常常希望设备不要因为空闲而自动进入睡眠模式或屏幕变暗。为了解决这一问题,WebAPI提供了一个名为WakeLock的接口,允许开发者请求设备保持唤醒状态。本文将详细介绍如何使用WakeLockAPI......
  • 设计一个高质量的API接口:提升应用性能的关键步骤
    在当今的软件开发世界中,API(应用程序编程接口)接口扮演着至关重要的角色。一个设计精良的API不仅能够提高开发效率,还能提升用户体验,并确保系统的可扩展性和安全性。本文将探讨如何设计一个高质量的API接口,并分析其对现代应用程序的重要性。什么是高质量的API接口?高质量的API接口通常......
  • ExtJs获取记录(Record)
    想要通过特定条件获取当前Store的某个Record一般常用两个方法findRecord和findNode这两个方法都有两个必选参数fieldName和value参数说明:fieldName:需要查找的record的字段名称,value:字段值带入sql语句会比较好理解select*from[表]{store}where[字段]{fieldName}......
  • 前端开发中的JS调试技巧
    调试技巧,在任何一项技术研发中都可谓是必不可少的技能。掌握各种调试技巧,必定能在工作中起到事半功倍的效果。譬如,快速定位问题、降低故障概率、帮助分析逻辑错误等等。而在互联网前端开发越来越重要的今天,如何在前端开发中降低开发成本,提升工作效率,掌握前端开发调试技巧尤为重......
  • Taobao API interface: keyword search product list data interface
    TaobaoAPIinterface:keywordsearchproductlistdatainterface——Ontheroadofgrowth,weareallfellowtravelers.IhopethisarticleabouttheTaobaoproductlistinformationinterfaceforproductselectioncanhelpyou.Ilookforwardtosharing......
  • Vue.js入门系列(三十一):Element-UI的基本使用与按需引入、Vue 3简介及使用 Vue CLI 与 V
    个人名片......
  • Vue.js入门系列(三十):深入理解独享路由守卫、组件内路由守卫、History模式与Hash模式
    个人名片......
  • 【JDK8新特性】Stream API 结合Lambda语法在项目中的实战应用
    Lambda语法回顾在JDK8中,Lambda表达式支持的引用类型主要有以下几种,如表1所示。种类Lambda表达式示例对应的引用示例类名引用普通方法(x,y,...)->对象名x.类普通方法名(y,...)类名::类普通方法名类名引用静态方法(x,y,...)->类名.类静态方法名(x,y,...)......