• React Promise 中断


    需求:

    • 上传文件,但是后端接口不支持多文件上传,但是一次性发出很多请求的话如果有100个文件那对后端的压力又太大了
    • 在上传的时候还需要有停止上传的按钮

    进程:

    • async await 只能做到第一步,但是无法在上传中的时候关闭这个进程,只能先隐藏进程然后等当前进程结束之后在代码下面加一个判定是不是已经关闭
    const uploadFile = async () => {
        isCancel.current = false;
        for (let i = 0; i < fileList.length; i++) {
          if (isCancel.current) {
            return;
          }
          const file = fileList[i]
          const res = await uploadFiles({ file })
          if (isCancel.current) {
            break;
          }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 但是这种做法只有在等 uploadFiles 里所有的东西都结束之后才能判定下一步的isCancel,但是这样会有一个问题,就是如果uploadFiles 执行时间很长,那么要么cancel 的执行时间会很长,要么就提前隐藏上传界面,但是这样有风险,如果用的人在cancel 的时候又点击了一下上传,那么就完了, 这个方法里的isCancel 又会变成 false,然后继续执行
    • 使用传统的 Promise 中的reject 方法可以随时停止这个异步行为
    const createCanCancelRequest = (requestFunc: () => Promise<any>) => {
      let func = () => {}
      const promise = new Promise((resolve, reject) => {
        func = () => reject("上传停止");
        requestFunc().then(resolve).catch(reject)
      })
      return { cancel: func, promise }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 这个方法接收一个传入的匿名函数,然后将匿名函数包裹在 Promise 里,执行并返回一个cancel 方法
    • 这个cancel 就是Promise 的 reject 方法,在调用这个方法之后未执行部分就会停止执行
    • 但是这个方法有个缺点就是要自己手动写一个sleep,在上一步执行完成之前,都不能停止sleep
    const uploadFile = async () => {
        isCancel.current = false;
        for (let i = 0; i < fileList.length; i++) {
          if (isCancel.current) {
            return;
          }
          const file = fileList[i]
          isBreak.current = false
          const {cancel, promise} = createCanCancelRequest(
            () => {
              uploadFiles({ file });
              isBreak.current = true
            }
          )
          while(1) {
            await new Promise(resolve => setTimeout(resolve, 1000));
            if (isBreak.current) {
              break
            }
          }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    拓展:

    • sleep 的逻辑,启动一个setTimeout 这是一个异步的实现,所以可以用 Promise 包起来并且做一个 await 就能实现暂停几秒的逻辑
  • 相关阅读:
    PyQt5 设置窗口背景
    k8s之Pod控制器详解
    【SA8295P 源码分析 (三)】126 - 摄像头 POC (Power over Coax) 同轴电缆供电技术原理分析
    mybatis 08: 返回主键值的insert操作 + 利用UUID获取字符串(了解)
    rocksdb 中 db_bench 的使用方法
    计组--存储系统
    故障预警 vs 故障分类:哪个更有意义,哪个更具挑战性?
    46_StringBuilder类
    Shell 脚本编程——变量和运算符
    基础 | 并发编程 - [导论 & volatile]
  • 原文地址:https://blog.csdn.net/weitao_11/article/details/133344547