Axios发布请求未使用cancelToken触发

时间:2020-10-08 21:33:47

标签: javascript reactjs axios

嗨,我有一个带有取消按钮的进度条,与文件上传有关。文件的上传触发进度条。有一个按钮可以取消上传过程。

作为取消上传的一部分,我调用了两个函数。一个先创建一个Axios cancelToken,然后创建一个包含该令牌的上传文件方法。

在我添加cancelToken之前,上传文件一直在工作,但是我仍然无法完全取消文件上传。有任何想法吗?我觉得我在cancelToken方面缺少一些步骤。

进度栏:

import React, { useState, useRef } from "react";
import { makeStyles } from "@material-ui/core/styles";
import LinearProgress from "@material-ui/core/LinearProgress";
import Typography from "@material-ui/core/Typography";
import { Grid, Theme, IconButton } from "@material-ui/core";
import Box from "@material-ui/core/Box";
import CloseIcon from "@material-ui/icons/Close";
import axios, { CancelToken, CancelTokenSource } from "axios";

interface Props {
  value: number;
  fileName: string;
  textStyle?: string;
  fileSize: number;
  textPadding?: string;
  cancelUpload?: () => void;
  // cancelFileUpload?: React.MutableRefObject<null>;
  source?: CancelTokenSource;
}

const useStyles = makeStyles((theme: Theme) => ({
  root: {
    width: "100%",
  },
  textStyle: {
    fontSize: 12,
  },
  textPadding: {
    marginBottom: theme.spacing(1),
  },
}));

const LinearProgressWithLabel: React.FC<Props> = ({
  value,
  fileName,
  textStyle,
  fileSize,
  textPadding,
  cancelUpload,
  // cancelFileUpload,
}) => (
  <Grid>
    <Grid className={textPadding}>
      <Typography className={textStyle} variant="body2" color="textPrimary">
        {fileName}
      </Typography>
    </Grid>

    <Grid className={textPadding}>
      <Typography className={textStyle} variant="body2" color="textPrimary">
        {`${(fileSize / (1024 * 1024)).toFixed(2)}MB`}
      </Typography>
    </Grid>

    <Grid>
      <Box width="100%" mr={1}>
        <LinearProgress variant="determinate" value={value} />
      </Box>
    </Grid>

    <Grid>
      <IconButton onClick={cancelUpload} color="inherit">
        <CloseIcon fontSize="small" />
      </IconButton>
    </Grid>

    <Grid>
      <Box minWidth={35}>
        <Typography variant="body2" color="textSecondary">
          {`${Math.round(value)}%`}
        </Typography>
      </Box>
    </Grid>
  </Grid>
);

const LinearWithValueLabel: React.FC<Props> = ({
  value,
  fileName,
  fileSize,
  cancelUpload,
}) => {
  const classes = useStyles();
  const [progress, setProgress] = useState(0);

  React.useEffect(() => {
    const timer = setInterval(() => {
      setProgress((prevProgress) => (prevProgress >= 100 ? 0 : progress));
    }, 800);
    return () => {
      clearInterval(timer);
    };
  }, []);

  return (
    <div className={classes.root}>
      <LinearProgressWithLabel
        value={value}
        fileName={fileName}
        textPadding={classes.textPadding}
        textStyle={classes.textStyle}
        fileSize={fileSize}
        cancelUpload={cancelUpload}
      />
    </div>
  );
};

export default LinearWithValueLabel;

let source: CancelTokenSource;

创建令牌:

export const deleteFileUploadProgress = async () => await deleteProgress();

export async function deleteProgress<T>() {
  source = axios.CancelToken.source();
};

上传文件:

export async function postFiles<T>(
  url: string,
  postForm: FormData,
  queryData: {} = {},
  handleProgress?: (progress: ProgressEvent) => void,
) {
    await axios.post(`${apiRoot}/${url}${objToQuery(queryData)}`, postForm, {
      headers: { 'Content-Type': 'application/json' },
      withCredentials: true,
      onUploadProgress: handleProgress,
      cancelToken: source.token,
    })
    .then(res => console.log(res))
    .catch(thrown => {
      if (axios.isCancel(thrown)) {
        console.log('Request canceled', thrown.message);
      }
    });

  if (true) {
    source.cancel('Request canceled!');
  }
};

1 个答案:

答案 0 :(得分:0)

如果将await放在之前 axios.post(...)之前,客户端/代码将等待服务器响应。因此,指令source.cancel()将始终在请求完成后 后执行。