大文件边压缩边下载,并实现进度条展示及错误自动重连

场景描述:一般情况下直接下载后台压缩好的大文件,通过onDownloadProgress方法可以直接获取该文件的大小以及实时下载的文件进度,实现下载进度条展示;此场景为后端边压缩前端边下载,此时文件总大小未知,不能使用onDownloadProgress方法获取文件总大小及下载进度。

转换思路:后台压缩过程较慢,但压缩之后浏览器下载过程默认可见,所以进度条主要是后台的文件压缩过程。

第一步:通过接口告知后台,前端将对此文件进行下载,后台接收到通知后生成唯一值并开始压缩文件,把唯一值返给前端
第二步:前端收到唯一值,之后通过轮询请求文件压缩过程接口,后台将此文件压缩状态及压缩进度不断返回给前端。
第三步:前端根据状态判断文件是否已经压缩完成,如果压缩完成:后台返回文件地址,前端自动或手动执行下载操作;如果没有完成:前端根据返回的压缩进度绘制进度条;如果报错:重新链接查询。

  • 通过pinia封装全局方法组件,以供相通场景快速使用

  • 代码逻辑准备,分析可能出现的问题及逻辑场景

可能出现的逻辑场景:

  1. 当前页面或缓存是否存在压缩任务
  2. 可以手动终止或开启查询
  • 封装查询方法
 const polling = async (processId:string, processFn: Function) => {
    getProcess(processId).then(process => {
      let {status, progressString, totalNum, successNum, failureNum, usedTime, percentComplete} = process.data
      if(status == '0'){ // 事件 -- 进行中
        if(cancelPolling.value) return
        window.setTimeout(() => {
          polling(processId, processFn)
        }, 500)
        return processFn({code: 300, msg: progressString, totalNum, successNum, failureNum, usedTime, percentComplete})
      }else if(status == '1'){ // 事件 -- 完成
        localStorage.removeItem('layout-processIds')
        if(failureNum){
          return processFn({code: 400, msg: progressString, totalNum, successNum, failureNum, usedTime, percentComplete})
        }else{
          return processFn({code: 200, msg: progressString, totalNum, successNum, failureNum, usedTime, percentComplete})
        }
      }else if(status == '2'){ // 事件 -- 存在异常
        localStorage.removeItem('layout-processIds')
        return processFn({code: 500, msg: progressString, percentComplete})
      }
    }).catch(() => {
      // 接口异常
      if(cancelPolling.value) return
      setTimeout(() => {
        polling(processId, processFn)
      }, 2000)
    })
  }
  • 检查是否存在压缩任务
const checkPolling = async (processFn: Function) => {
    let processId = localStorage.getItem("layout-processIds") || ""
    if(processId){
      cancelPolling.value = false
      let res = await polling(processId, processFn)
      return res
    }else{
      return {code: 500, msg: '本地不存在文件任务'}
    }
  }
  • 开启/关闭压缩任务
// 开启压缩任务
const startPolling = async (processId: string, processFn: Function) => {
    localStorage.setItem("layout-processIds", processId)
    cancelPolling.value = false
    let res = await polling(processId, processFn)
    return res
  }
// 关闭压缩任务
const endPolling = async () => {
    cancelPolling.value = true
  }
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值