为了账号安全,请及时绑定邮箱和手机立即绑定

如何在循环内使用回调?

如何在循环内使用回调?

慕妹3242003 2021-10-14 14:27:21
背景是我允许用户将多个文件拖入 Dropzone。我需要检查每种文件类型。如果其中一个不允许,设置消息并早点离开。请参阅下面的代码 Starts at for (let i = 0; i < acceptedFiles.length; i++) { Inside this for loop, I call reader.onloadend,这是一个回调。如何在 for 循环中运行回调?// Keep it internal  const getMimetype = signature => {    switch (signature) {      case '89504E47':        return 'image/png';      case '47494638':        return 'image/gif';      case '25504446':        return 'application/pdf';      case 'FFD8FFDB':      case 'FFD8FFE0':        return 'image/jpeg';      case '504B0304':        return 'application/zip';      default:        return 'Unknown filetype';    }  };  const onDropAccepted = useCallback(acceptedFiles => {    // reset to default state    resetToDefaultState();    //test    console.log('acceptedFiles', acceptedFiles);    // reader    const reader = new FileReader();    let file;    // Multi    if (config.isMultipleFiles === true) {      // Loop all files and check file types      for (let i = 0; i < acceptedFiles.length; i++) {        file = acceptedFiles[i];        // get 1st 4 byptes        const blob = file.slice(0, 4);        reader.readAsArrayBuffer(blob);        reader.onloadend = evt => {          if (evt.target.readyState === FileReader.DONE) {            const uint = new Uint8Array(evt.target.result);            let bytes = [];            uint.forEach(byte => {              bytes.push(byte.toString(16));            });            const hex = bytes.join('').toUpperCase();            const type = getMimetype(hex);            // type is allowed            if (config.fileTypes.includes(type)) {              setFiles([...files, ...acceptedFiles]);            } else {              // type no good              setIsInvaildFileType(true);            }          }        };      }    } 
查看完整描述

1 回答

?
慕桂英546537

TA贡献1848条经验 获得超10个赞

我还必须以react-dropzone类似的方式验证每个文件。

我的解决方法是承诺FileReader.


1️⃣ This is the promisified version of "FileReader"

const isValidFile = file => {

  return new Promise((resolve, reject) => {

    const reader = new FileReader();

    reader.onloadend = evt => {

      // other logic removed for brevity...


      2️⃣ Your custom logic dictates, if the file is valid or not

      if (config.fileTypes.includes(type)) {

        resolve(true);

      } else {

        resolve(false);

      }

    };


    3️⃣ Should there was an error, this file is not good.

    reader.onerror = () => resolve(false)


    4️⃣ Start the reading process.

    const blob = file.slice(0, 4);

    reader.readAsArrayBuffer(blob);

  });

};

现在您可以在for您提到的循环中使用它。


const onDropAccepted = useCallback(acceptedFiles => {

  // reset to default state

  resetToDefaultState();


  1️⃣ As `useCallback` accepts a non-async method,

      Create a wrapped async method we can call here.

  const processFiles = async () => {

    if (config.isMultipleFiles === true) {

      for (let i = 0; i < acceptedFiles.length; i++) {

        const file = acceptedFiles[i];

        2️⃣ Here is where we validate the file using the code above.

        const isValid = await isValidFile(file);

        if (!isValid) {

          setIsInvaildFileType(true);

          return;

        }

      }


      3️⃣ At this point, all files are good.

      setFiles([...files, ...acceptedFiles]);

    } else {

      // removed for brevity...

    }

  };


  4️⃣ Let's fire up the process

  processFiles();

});


查看完整回答
反对 回复 2021-10-14
  • 1 回答
  • 0 关注
  • 177 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信