让JS函数返回值,而不是在onload=function()里面写冗长的代码

问题描述 投票:0回答:1

下面是一个检测输入文件是否为 JPEG 的函数(经测试),它工作得很好。抱歉,我不习惯 JS 的异步特性,想知道...是否有办法让这个函数返回一个值,并且可以像这样使用:

MyMainFunction()  {
  // code goes in here
  // lengthy code block

  if ( validateFile() == false )  {
    // show warning
    return;
  }
  
  // keep writing code to process JPEG
  // and more as we get valid input
  // lengthy code...
 
}

function validateFile() {
  var blob = document.getElementById('filex1').files[0].slice(0,12);
  document.getElementById('filex1').value=null;
  var fileReader3 = new FileReader();
  fileReader3.readAsArrayBuffer(blob);
        
  fileReader3.onload = function(someVar) {
    var arr = (new Uint8Array(someVar.target.result)).subarray(0, 4);
    var header = "";
    for(var i = 0; i < arr.length; i++) {
      header += arr[i].toString(16);
    }
    if (['ffd8ffe0', 'ffd8ffe1', 'ffd8ffe2', 'ffd8ffe3', 'ffd8ffe8'].includes(header))  {
      console.log(header, ': JPEG File Detected');
/*    Continue writing a lengthy code here or call another
      function containing main code.
      While keeping blob, fileReader3 and all other variables
      in memory which are basically useless after
      detecting file type
*/
    }
    else    {
      console.log(header, ': Invalid File Type');
/*    Show warning to user and do nothing.. code ends here  */
    }
  }
}
<input type='file' id='filex1' onchange='validateFile()'>

编辑:我不想使用回调...我已经遵循在 onload=function() 块内完成检查后调用主函数的概念。而且我发现 myMainFunction 不适合声明为异步。

javascript asynchronous filereader onload
1个回答
0
投票

开发! 为了使 validateFile 函数同步返回值,我们需要调整代码以处理 JavaScript 的异步特性。使用 FileReader 读取文件是异步的,这意味着 validateFile 函数不能简单地直接返回值。不过,我们可以使用 Promises 来处理这种情况,让代码“等待”文件读取完成后再继续执行。

例如:

function validateFile() {
  return new Promise((resolve, reject) => {
    var blob = document.getElementById('filex1').files[0].slice(0, 12);
    document.getElementById('filex1').value = null;
    var fileReader3 = new FileReader();
    fileReader3.readAsArrayBuffer(blob);
    
    fileReader3.onload = function(someVar) {
      var arr = (new Uint8Array(someVar.target.result)).subarray(0, 4);
      var header = "";
      for (var i = 0; i < arr.length; i++) {
        header += arr[i].toString(16);
      }
      if (['ffd8ffe0', 'ffd8ffe1', 'ffd8ffe2', 'ffd8ffe3', 'ffd8ffe8'].includes(header)) {
        console.log(header, ': JPEG File Detected');
        resolve(true);  // JPEG file detected, returns true
      } else {
        console.log(header, ': Invalid File Type');
        resolve(false);  // Invalid file type, returns false
      }
    };

    fileReader3.onerror = function() {
      reject('Error reading file');  // In case of error, reject the promise
    };
  });
}

async function MyMainFunction() {
  const isValid = await validateFile();
  if (!isValid) {
    // display warning
    return;
  }
}

© www.soinside.com 2019 - 2024. All rights reserved.