Streams API

前端精髓

共 3897字,需浏览 8分钟

 · 2021-11-22

Streams API允许JavaScript以编程的方式访问通过网络接收的数据流,并根据开发人员的需要处理它们。


概念和用法 流将你希望通过网络接收的资源拆分成小块,然后按位处理它。这正是浏览器在接收用于显示web页面的资源时做的事情——视频缓冲区和更多的内容可以逐渐播放,有时候随着内容的加载,你可以看到图像逐渐地显示。


但曾经这些对于JavaScript是不可用的。以前,如果我们想要处理某种资源(如视频、文本文件等),我们必须下载完整的文件,等待它反序列化成适当的格式,然后在完整地接收到所有的内容后再进行处理。


随着流在JavaScript中的使用,一切发生了改变——只要原始数据在客户端可用,你就可以使用JavaScript 按位处理它,而不再需要缓冲区、字符串或blob。



还有更多的优点——你可以检测流何时开始或结束,将流链接在一起,根据需要处理错误和取消流,并对流的读取速度做出反应。


流的基础应用围绕着使响应可以被流处理展开。例如,一个成功的 fetch request 响应 Body 会暴露为 ReadableStream,之后你就可以使用 ReadableStream.getReader() 建立的 reader 读取它,使用 ReadableStream.cancel() 取消它等等。


fetch("https://www.example.org/").then((response) => {  const reader = response.body.getReader();  const stream = new ReadableStream({    start(controller) {      // 下面的函数处理每个数据块      function push() {        // "done"是一个布尔型,"value"是一个Uint8Array        reader.read().then(({ done, value }) => {          // 判断是否还有可读的数据?          if (done) {            // 告诉浏览器已经结束数据发送            controller.close();            return;          }
// 取得数据并将它通过controller发送给浏览器 controller.enqueue(value); push(); }); };
push(); } });
return new Response(stream, { headers: { "Content-Type": "text/html" } });});

ArrayBuffer

ArrayBuffer 对象用来表示通用的、固定长度的原始二进制数据缓冲区。


它是一个字节数组,通常在其他语言中称为“byte array”。


// create an ArrayBuffer with a size in bytesconst buffer = new ArrayBuffer(8);
console.log(buffer.byteLength);// expected output: 8

Blob

Blob 对象表示一个不可变、原始数据的类文件对象(类文件对象:其实就是类似于文件的对象。)。它的数据可以按文本或二进制的格式进行读取,也可以转换成 ReadableStream 来用于数据操作。


Blob 表示的不一定是JavaScript原生格式的数据。File 接口基于Blob,继承了 blob 的功能并将其扩展使其支持用户系统上的文件。


File 对象是特殊类型的 Blob,且可以用在任意的 Blob 类型的 context 中。


Blob.stream() 返回一个能读取blob内容的 ReadableStream。


Blob.text() 返回一个promise且包含blob所有内容的UTF-8格式的 USVString。


Blob.arrayBuffer() 返回一个promise且包含blob所有内容的二进制格式的 ArrayBuffer


Blob() 构造函数允许通过其它对象创建 Blob 对象。比如,用字符串构建一个 blob:


var debug = {hello: "world"};var blob = new Blob([JSON.stringify(debug, null, 2)], {type : 'application/json'});

FileReader

FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。


其中File对象可以是来自用户在一个  元素上选择文件后返回的FileList对象,也可以来自拖放操作生成的 DataTransfer对象。


使用 FileReader() 构造器去创建一个新的 FileReader。


FileReader.onload 处理 load 事件。该事件在读取操作完成时触发。


FileReader.result 只读 文件的内容。该属性仅在读取操作完成后才有效,数据的格式取决于使用哪个方法来启动读取操作。


FileReader.readAsArrayBuffer() 开始读取指定的 Blob中的内容, 一旦完成, result 属性中保存的将是被读取文件的 ArrayBuffer 数据对象.


FileReader.readAsBinaryString() 开始读取指定的Blob中的内容。一旦完成,result属性中将包含所读取文件的原始二进制数据。


FileReader.readAsDataURL() 开始读取指定的Blob中的内容。一旦完成,result属性中将包含一个data: URL格式的Base64字符串以表示所读取文件的内容。


FileReader.readAsText() 开始读取指定的Blob中的内容。一旦完成,result属性中将包含一个字符串以表示所读取的文件内容。

相互转化

1. dataURL(base64) 转化成 Blob(二进制)对象

function dataURLToBlob(fileDataURL) { let arr = fileDataURL.split(','),     mime = arr[0].match(/:(.*?);/)[1],     bstr = atob(arr[1]),     n = bstr.length,     u8arr = new Uint8Array(n); while(n --) {   u8arr[n] = bstr.charCodeAt(n) } return new Blob([u8arr], {type: mime})}

      2. File、Blob 文件数据绘制到 canvas

// 思路:File, Blob ——> dataURL ——> canvas
function fileAndBlobToCanvas(fileDataURL) { let img = new Image() img.src = fileDataURL let canvas = document.createElement('canvas') if(!canvas.getContext) { alert('浏览器不支持canvas') return; } let ctx = canvas.getContext('2d') document.getElementById('container').appendChild(canvas) img.onload = function() { ctx.drawImage(img, 0, 0, canvas.width, canvas.height) }}

2.File、Blob 转化成 dataURL

function fileToDataURL(file) {    let reader = new FileReader()    reader.readAsDataURL(file)    // reader 读取文件成功的回调    reader.onload = function(e) {      return reader.result    }}

4.从 canvas 中获取文件 dataURL

function canvasToDataURL() {    let canvas = document.createElement('canvas')    let canvasDataURL = canvas.toDataURL('image/png', 1.0)    return canvasDataURL}


浏览 29
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报