如何中断promise.all

NANA
  • 94
发送文件
getFn(file) {
  const formdata=new FormData();
        formdata.append('file',file);
      
        return this.$axios({
          method: "post",
          url: "/upload",
          data: formdata,
          headers: {
            "Content-Type": "application/x-www-form-urlencoded;"
          }
        }).then(res=> {
          console.log(res, 78);
        }).
}
利用promisep批量发送文件
sendFile() {
 const lists = [getFn(file1), getFn(file2), getFn(file3)]
 promise.all(lists)
}

问题 ?点击终止如何停止发送所有文件

点击终止停止发送所有文件 
closeFile() {
      ???
      
},
回复
阅读 2.3k
3 个回答

在axios里 添加了中断请求的方法

 cancelToken: new CancelToken(c => {  //强行中断请求要用到的
    this.cancel.push(c)
}),

点击终止停止发送所有文件

closeFile() {
    this.cancel.forEach(fn=> {
      fn('中断请求')
    })   
},

Promise 本身没有设计中断方法,fetch 支持配合 abortController 中断,查阅 axios 文档 有一个 CancelToken 以非常相似的形式中断。

其中 source 对应 abortControllersource.token 对应 abortController.signal,可参照 HTML 规范要求 设计 CancelToken 形式的可中止 getFn

getFn(file, { cancelToken } = {}) {
  cancelToken?.throwIfRequested();

  const formdata = new FormData();
  formdata.append('file', file);

  const axiosConfig = {
    method: 'post',
    url: '/upload',
    data: formdata,
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded;',
    },
  };

  if (cancelToken) axiosConfig.cancelToken = cancelToken;

  return this.$axios(axiosConfig)
    .then((res) => {
      console.log(res, 78);
    });
}

然后改写 sendFile 方法形如:

sendFile(fileArr) {
  const { token, cancel } = CancelToken.source();
  this.cancel = cancel;
  return Promise.all(fileArr.map((file) => getFn(file, { cancelToken: token }));
}

closeFile 就可以写成:

closeFile() {
  this.cancel();
}

标准Promises/A+ 协议没有中断的方法,但是可以利用三方Promise包实现(比如:bluebird

以下只是演示,具体代码需要根据你的需求改造

import {Promise} from "bluebird";

Promise.config({ cancellation: true }); // 启用非标准特性:设置为可中断


const promises = [getFn(file1), getFn(file2), getFn(file3)];

Promise.all(promises)

closeFile() {
     promises.forEach(p => p.cancel()); // 依次取消  
}

closeFile() // 点击的时候执行这个函数
       
宣传栏