开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第15天,点击查看活动详情
前言
上一节我们针对前端较大数据传输所造成的页面响应缓慢的问题,使用了分片的思路进行优化处理,但是由于分片会对字节码进行截取,导致了在文本解析的过程中在截取位置出现了乱码的问题,本节将针对这一问题,做进一步的优化,不废话马上开始
参考代码
为了保障字符能够正常解析,我们需要找到一个特殊的值来对字节数组进行截取,说实话这个特殊值是我看了相关的代码反推出来的,先看下完整的代码
async function loadText (url) {
const res = await fetch(url)
// 传输了多少读多少
const reader = await res.body.getReader()
const decoder = new TextDecoder() // 文本解码器
let flag = false
let remainChunk = new Uint8Array(0)
while(!flag) {
const { value, done } = await reader.read()
// console.log(done); // 加载状态
// console.log(value); // 字节数组
flag = done
if (flag) return
const lastIndex = value.lastIndexOf(10) // 数值10位置进行切分
const chunk = value.slice(0, lastIndex + 1)
const readChunk = new Uint8Array(remainChunk.length + chunk.length)
readChunk.set(remainChunk);
readChunk.set(chunk, remainChunk.length)
remainChunk = value.slice(lastIndex + 1)
const text = decoder.decode(readChunk)
console.log('======');
console.log(text)
}
}
这段代码琢磨了许久,通过使用了一些特殊的字节数组解析出来猜测,10这个位置要么应该是一个换行符(若有相关资料,望大佬留言指教)
const decoder = new TextDecoder() // 文本解码器
console.log(decoder.decode(new Uint8Array([155,135,227,128,130,10])))
思路
计算解析数组的长度
找到 10 这个分割点后,后面的事情就简单多了,我们只需要每次读取到片段时,只解析上一次的末尾开始到这一次10处即可
const { value, done } = await reader.read()
const lastIndex = value.lastIndexOf(10) // 记录本次最后一个 10 的位置
const chunk = value.slice(0, lastIndex + 1) // 截取本次数组
// 以上一次未解析的内容长度 + 本次需要解析的长 = 需要初始化的字节数组长度
const readChunk = new Uint8Array(remainChunk.length + chunk.length)
加载数组内容
readChunk.set(remainChunk) // 从 0 开始,加载上一次未解析内容
readChunk.set(chunk, remainChunk.length) // 从上一次未解析内容末尾开始,加载本次内容
暂存本次未解析内容
remainChunk = value.slice(lastIndex + 1)
解析本次内容并展示
const text = decoder.decode(readChunk)
console.log('======');
console.log(text)
好了,本篇针对txt文本文件分片加载的优化到此告一段路,感觉对网络数据的传输又有了新的认识,由于写该主题时明显感觉有些吃力,也意识到了自己的很多不足,后面再接再厉,争取把相关知识点搞懂搞透