文件读取器未保持秩序

eqfvzcg8  于 2021-09-13  发布在  Java
关注(0)|答案(1)|浏览(287)

我正在做一个带有预览的多图像上传组件,我有一个问题,这个问题只会在做图像预览的代码中偶尔出现。

useEffect(() => {
    if (props.images.length > 0) {
      setPreview([]);
      for (const image of props.images) {
        if (image.type) {
          //fileChanger(props.images);
          const reader = new FileReader();
          reader.onloadend = () => {
            setPreview((prevState) => {
              return prevState.concat(reader.result)});
              //image.name
          };

          reader.readAsDataURL(image);
        } else {
          setPreview((prevState) => prevState.concat(image));
        }
      }
    } else if (props.images === null) {
      //fileChanger(props.images);

      setPreview(null);
    }
  }, [props.images, fileChanger]);

问题是图像的预览顺序与原始数组(props.images)中显示的顺序不同。我想这可能是因为 reader.onloadend 拍摄一些图片需要更长的时间,但我不确定,我正在寻找一个可能的修复建议。

suzh9iv8

suzh9iv81#

你是对的,这个问题是由 reader.onloadend 多亏了它,您可以异步并行加载图像,所以无法保证触发事件的顺序。如果您需要图像的顺序与输入时的顺序相同,则必须引入一些同步。
如:

useEffect(() => {
    if (props.images.length > 0) {
      setPreview([]);

      let toLoad = props.images.length;
      let loadedImages = [];

      let synchronizedPreview = (const ordinal, const image) => {
        loadedImages[ordinal] = image;
        if (--toLoad > 0) return;
        for (const loadedImage of loadedImages) {
          setPreview((prevState) => prevState.concat(loadedImage));
        }
      };

      let index = 0;
      for (const image of props.images) {
        const ordinal = index++;
        if (image.type) {
          //fileChanger(props.images);
          const reader = new FileReader();
          reader.onloadend = () => {
            synchronizedPreview(ordinal, reader.result);
          };

          reader.readAsDataURL(image);
        } else {
          synchronizedPreview(ordinal, image);
        }
      }

    } else if (props.images === null) {
      //fileChanger(props.images);

      setPreview(null);
    }
  }, [props.images, fileChanger]);

相关问题