从 FileReader() 返回结果?

Returning results from FileReader()?

我正在尝试制作一个简单的 csv 到 JSON 转换器(只是为了练习),但我还没有找到任何方法来使用 [=27] 从 FileReader() 函数中获取数据=].我不知道这是否可能。

那么下面的代码做了什么:它只是抓取一个 csv 文件并在按下按钮后尝试 运行 一个将它转换为数组的函数(到目前为止)。打印数组的是 console.log ,它工作正常,但是如果我想 return 这个数组,以便我可以将它传递给另一个函数怎么办?每当我使用 return csvArray; 然后而不是 运行 宁函数试图 console.log(fileToArray(fileinput)); 我得到未定义。我还没有在网上找到任何关于使用 vanilla JS 的内容。

const fileinput = document.querySelector("#csvfile").files[0];
const convertBtnFile = document.querySelector("#convertBtn");

convertBtnFile.addEventListener("click", (e) => {
  e.preventDefault();
  fileToArray(fileinput);
});

const fileToArray = (csvFile) => {
  const myFile = new FileReader();
  myFile.onload = (event) => {
    const wholeText = event.target.result;
    const splitLines = wholeText.split(/\r\n|\n/);
    csvArray = splitLines.map(i => i.split(","));
    console.log(csvArray);
  }
  myFile.readAsText(csvFile);
}
<input type="file" id="csvfile" /><br/> <button type="button" id="convertBtn">Convert</button>

你的代码做错了一件事是

const fileinput = document.querySelector("#csvfile").files[0];

立即 - 您想等到进入点击处理程序后再尝试读取文件

最简单的答案是在 fileToArray 函数中使用回调

const convertBtnFile = document.querySelector("#convertBtn");

convertBtnFile.addEventListener("click", (e) => {
    e.preventDefault();
    const fileinput = document.querySelector("#csvfile").files[0];
    fileToArray(fileinput, data => {
        // do things with results here *********
    });
});

const fileToArray = (csvFile, cb) => { // ********
    const myFile = new FileReader();
    myFile.onload = (event) => {
        const wholeText = event.target.result;
        const splitLines = wholeText.split(/\r\n|\n/);
        csvArray = splitLines.map(i => i.split(","));
        cb(csvArray); // **** call the supplied function with the results
    }
    myFile.readAsText(csvFile);
}

如果您对 async/await 感到满意,您可以这样做 - 好处是,它“看起来”是同步的

const convertBtnFile = document.querySelector("#convertBtn");

//                                 note: vvvvv async
convertBtnFile.addEventListener("click", async (e) => {
    e.preventDefault();
    const fileinput = document.querySelector("#csvfile").files[0];
    const data = await fileToArray(fileinput);
    // do things here
});

const fileToArray = csvFile => {
    return new Promise((resolve, reject) => {
        const myFile = new FileReader();
        myFile.onload = event => {
            const wholeText = event.target.result;
            const splitLines = wholeText.split(/\r\n|\n/);
            csvArray = splitLines.map(i => i.split(","));
            resolve(csvArray);
        }
        myFile.onerror = reject;
        myFile.readAsText(csvFile);
    });
};