【问题标题】:File Reader not keeping order文件阅读器不保持秩序
【发布时间】:2021-07-11 15:26:15
【问题描述】:

我正在做一个带预览的多图像上传组件,但我遇到的问题仅在执行图像预览的代码段时才会发生。

  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 处理某些图像的时间更长,但我不确定,我正在寻找可能的修复建议。

【问题讨论】:

    标签: javascript reactjs filereader


    【解决方案1】:

    您说得对,问题是由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]);
    

    【讨论】:

    • 此代码与我的代码结合使用时存在一些问题,因为 image 未定义,因为您使用 for (var i = 0; i < props.images.length; i++) 作为循环而不是我使用的 for of。我已经修改了代码,它可以工作,谢谢。 :)
    • 是的,抱歉,JavaScript 不是我的菜... :D 上次我接触它是在 4 年前,但谢天谢地,你明白了。
    猜你喜欢
    • 2018-04-17
    • 2017-05-29
    • 1970-01-01
    • 2013-07-22
    • 2017-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多