使用Promise.all时Axios POST请求返回空数组

时间:2020-10-13 12:34:01

标签: javascript ajax typescript promise axios

requests解决时,我的Promise.all数组中没有任何承诺状态。

我在做错什么,因为我认为使用axios post方法会返回一个诺言?

  const doUpload = async (fileList: FileList) => {
    const requests: Array<void | AxiosResponse<any>> = [];

    Array.from(fileList).forEach(async file => {
      const formData = new FormData();
      const blob = new Blob([file]);
      formData.append(file.name, blob);

      requests.push(
        await axios
          .post(
            'https://jsonplaceholder.typicode.com/posts',
            {
              ...formData,
            },
            {
              headers: {
                'Content-Type': 'multipart/form-data',
              },
              onUploadProgress: (progressEvent: ProgressEvent) =>
                handleUploadProgress(progressEvent, file.lastModified),
            }
          )
          .catch(error => {
            handleUploadError(file.lastModified);
          })
      );
    });

    try {
      const data = await Promise.all(requests);
      console.dir(data);
    } catch (error) {
      console.log(error);
    }
  };

2 个答案:

答案 0 :(得分:3)

Jeremy的权利是您的代码中有不必要的await,但是主要的问题是您将catch处理程序放在post的promise上,从而隐藏了promise拒绝。然后让该处理程序完成而不会引发错误或返回任何内容。这样会将拒绝变成价值undefined的满足。

(可能)删除catch处理程序,或者让它返回一些内容,您可以用来了解post失败。


FWIW,下面是一个示例,该操作使用Array.from的映射功能(因为您正在执行映射操作);查看评论:

const doUpload = async (fileList: FileList) => {
  // Use `map`
  const requests = Array.from(fileList, file => {
    const formData = new FormData();
    const blob = new Blob([file]);
    formData.append(file.name, blob);

    // No need for `await` here
    return axios.post(
      'https://jsonplaceholder.typicode.com/posts',
      {
        ...formData,
      },
      {
        headers: {
          'Content-Type': 'multipart/form-data',
        },
        onUploadProgress: (progressEvent: ProgressEvent) =>
          handleUploadProgress(progressEvent, file.lastModified),
      }
    );
    // No `.catch` here (or have one, but make it return something useful
  });

  try {
    const data = await Promise.all(requests);
    console.dir(data);
  } catch (error) {
    console.log(error);
  }
};

如果您需要在其中的某个地方调用handleUploadError,则可以考虑使用Promise.allSettled(相对较新)而不是Promise.all,然后针对数组中给出的所有被拒绝的promise进行调用你。


...使用Promise.all解决时。

请注意:使用Promise.all不会“解决”您传递给它的承诺。只是观察它们发生了什么。诺言将会解决,但是无论您是否使用Promise.all,诺言都会解决。

一些可能有用的承诺术语:

  • 完成-使用特定的实现值 待处理更改为已实现 >
  • 拒绝-通过特定的拒绝原因 待处理更改为已拒绝 >
  • 解决-直接(通过履行或拒绝)或通过确定间接(通过使结果取决于另一个承诺的结果)确定一个承诺的最终结果

答案 1 :(得分:2)

您正在将已解决的Promises推送到阵列(requests.push(await axios.post()))。无需等待即可推送承诺(requests.push(axios.post()))。然后Promise.all可以完成工作。

const doUpload = async(fileList: FileList) => {
    const requests: Array < void | Promise<any> > = [];

    Array.from(fileList).forEach( file => {
        const formData = new FormData();
        const blob = new Blob([file]);
        formData.append(file.name, blob);

        requests.push(axios.post(/* ... */ ));
    });

    try {
        const data = await Promise.all(requests);
        console.dir(data);
    } catch (error) {
        console.log(error);
    }
};