返回的JSON 数据量太大时, 前端如何切片下载

378 阅读1分钟

存在的问题:

针对 BI 等大数据展示的项目,有些数据后端没办法做分页,那么就会导致返回的数据量很大, 比如几十M的json数据, 还不等优化setState 浏览器就崩溃了

const res = await fetch()
const json = await res.json() // 貌似是这里一次性解析的数据量太大

解决办法:

这里需要用流的方式去接受数据,在返回数据流的过程中就接受和展示数据

const load = async ()=>{
      const  resp =  await fetch('https://jsonplaceholder.typicode.com/photos')
      const reader = resp.body.getReader()
      const decoder = new TextDecoder()
      let count = 0
      while(true){
         const {value,done} = await reader.read()
         if(done){
            break;
         }
         const text = decoder.decode(value)
         console.log(`${count++} >>>`, text)
    }
}

image.png

存在问题,对象会被切分在两个chunk里,需要处理一下, 利用 { 来切分字符串为一个对象

const load = async () => {
  const resp = await fetch('https://jsonplaceholder.typicode.com/photos');
  const reader = resp.body.getReader();
  const decoder = new TextDecoder();
  let remainChunk = new Uint8Array(0);
  let num = 0;
  for (;;) {
    const { value, done } = await reader.read();
    if (done) {
      break;
    }

    const charCode = '{'.charCodeAt(0) // 123
    const lastIndex = value.lastIndexOf(charCode);
    const chunk = value.slice(0, lastIndex);
    const readChunk = new Uint8Array(remainChunk.length + chunk.length);
    readChunk.set(remainChunk);
    readChunk.set(chunk, remainChunk.length);
    remainChunk = value.slice(lastIndex);

    const text = decoder.decode(readChunk);
    console.log(`text${num++}`, text);
  }

  const text = decoder.decode(remainChunk);
  console.log('textRemain', text);
};

image.png

可以看到现在已经好了

更加完善的解析方法应该是JSONParse, 参考 手写jsonParse