How to implement breakpoint continuation when multiple fetch API work at the same time

122 Views Asked by At

I need to request a large file in pieces and construct a new readablestream from the response.

At first, I only requested one piece of data at a time, and on this basis, I realized the breakpoint continuation to deal with the instability of the network

let _this = this
let responseList = []
let response = null
let reader = null
let offset = 0
let start = 0
let end = start + this.RANGE_SIZE
return new ReadableStream({
  async start(controller) {
    responseList.push(await fetch(_this.url, {responseType: 'blob', headers: {range: `bytes=${start}-${end}`}}))
    reader = responseList[0].body.getReader()
  },
  async pull(controller) {
    try {
      var {done, value} = await reader.read()
    } catch (e) {
      let errorOffset = 0
      responseList[0] = await fetch(_this.url, {responseType: 'blob', headers: {range: `bytes=${start}-${end}`}})
      reader = responseList[0].body.getReader()
      while (true) {
        let {done, value} = await reader.read()
        if (errorOffset + value.length > offset){
          value = value.slice(offset - errorOffset)
          controller.enqueue(value)
          return
        }else {
          errorOffset += value.length
        }
      }
    }

    if (done) {
      offset = 0
      start = end + 1
      end += _this.RANGE_SIZE
      responseList.shift()

      responseList.push(await fetch(_this.url, {responseType: 'blob', headers: {range: `bytes=${start}-${end}`}}))
      reader = responseList[0].body.getReader()
      const {done, value} = await reader.read()
      controller.enqueue(value)
      offset += value.length
    } else {
      controller.enqueue(value)
      offset += value.length
    }
  }
})

But now I want to download two slices at the same time to improve the download efficiency.

  async start(controller) {
    responseList.push(await fetch(_this.url, {responseType: 'blob', headers: {range: `bytes=${start}-${end}`}}))
    start = end + 1
    end += _this.RANGE_SIZE
    responseList.push(await fetch(_this.url, {responseType: 'blob', headers: {range: `bytes=${start}-${end}`}}))
    reader = responseList[0].body.getReader()
  },

In this case, I cannot get whether the second reader has failed. try...catch... not work.

Is there a way to solve this problem

0

There are 0 best solutions below