在React、Redux和Axios中并行/顺序调用API

jogvjijk  于 2022-11-12  发布在  React
关注(0)|答案(1)|浏览(167)

我需要确定我是否需要上传照片(调用上传API)顺序或并行。
顺序意味着当您上传图像(调用上传API)时,您将等待第一个图像被解析,然后显示图像,然后再调用下一个上传API。
并行意味着当你上传图像时,你会显示任何首先被解析的图像。所以你可以同时显示图像,因为多个响应可以在这里被解析。
我希望在一个uploadPhotos动作中有一个条件,即是顺序还是并行。条件是当它包含相同的文件名时使用顺序,例如如果你上传aa_11-01.jpg,那么你上传aa_11-02.jpg,否则使用并行。
请始终记住,仅在最后一个-xxx之前进行识别
比如说。

aa_11-01.jpg        -      aa_11
aa-11-01.jpg        -      aa-11
aa.jpg              -      aa
aa-12j-14kkk.jpg    -      aa-12j
test-a.jpg          -      test
test-b.jpg          -      test

并行

export const uploadPhotos =
  ({ photos, size, controller }) =>
  async (dispatch) => {
    photos.forEach(async (photo, index) => {
      const formData = new FormData();
      formData.append(photo?.imageFileName, photo?.imageFile)

      dispatch({ type: constants.UPLOAD_PHOTOS_START, size });
      try {
        const response = await axios.post(
          `${API_URL}/photos/upload`,
          formData,
          {
            onUploadProgress({ loaded, total }) {
              dispatch(setUploadProgress({ id: index, loaded, total }));
            },
            signal: controller.signal,
          }
        );

        dispatch({
          type: constants.UPLOAD_PHOTOS_SUCCESS,
          payload: response.data,
        });
      } catch (error) {
        dispatch({
          type: constants.UPLOAD_PHOTOS_FAILURE,
          payload: error,
        });
      }
    });
  };

连续

export const uploadPhotos =
      ({ photos, size, controller }) =>
      async (dispatch) => {
        for (const [index, photo] of photos.entries()) {
          const formData = new FormData();
            formData.append(photo?.imageFileName, photo?.imageFile)

          dispatch({ type: constants.UPLOAD_PHOTOS_START, size });
          try {
            const response = await axios.post(
              `${API_URL}/photos/upload`,
              formData,
              {
                onUploadProgress({ loaded, total }) {
                  dispatch(setUploadProgress({ id: index, loaded, total }));
                },
                signal: controller.signal,
              }
            );

            dispatch({
              type: constants.UPLOAD_PHOTOS_SUCCESS,
              payload: response.data,
            });
          } catch (error) {
            dispatch({
              type: constants.UPLOAD_PHOTOS_FAILURE,
              payload: error,
            });
          }
        }
      };
w8ntj3qf

w8ntj3qf1#

在发出任何请求之前,您可以首先分析文件名并将数组分组为子数组,其中子数组包含具有“name-sequence.ext”模式的文件名(“sequence”可以是任何内容)。不包含此序列部分的文件名将作为子数组中的唯一条目结束。
然后混合两个循环,forEach作为外部循环,for作为内部循环:

export const uploadPhotos = 
  ({ photos, size, controller }) =>
  async (dispatch) => {
    // Identify the part of the file name that excludes the (optional) sequence number
    const keyedphotos = photos.map(photo => [photo.imageFileName.replace(/-\w+\.\w+$/, ""), photo]);
    // Create a group for each such prefix
    const map = new Map(keyedphotos.map(([key]) => [key, []]));
    // Populate those groups
    for (const [key, photo] of keyedphotos) map.get(key).push(photo)
    // And extract those groups into an array (of subarrays)
    const photoGroups = [...map.values()];
    let index = 0; // Keep the index counter separate

    photoGroups.forEach(async (photos) => { // Iterate the groups that can run in parallel
      for (const photo of photos) { // Iterate the photos that should run sequentially
        const id = index++; // Get the next unique id
        const formData = new FormData();
        formData.append(photo?.imageFileName, photo?.imageFile)

        dispatch({ type: constants.UPLOAD_PHOTOS_START, size });
        try {
          const response = await axios.post(
            `${API_URL}/photos/upload`,
            formData,
            {
              onUploadProgress({ loaded, total }) {
                dispatch(setUploadProgress({ id, loaded, total })); // Use id
              },
              signal: controller.signal,
            }
          );

          dispatch({
            type: constants.UPLOAD_PHOTOS_SUCCESS,
            payload: response.data,
          });
        } catch (error) {
          dispatch({
            type: constants.UPLOAD_PHOTOS_FAILURE,
            payload: error,
          });
        }
      }
    });
  };

相关问题