FileReader readAsText() 异步问题?

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

我已经实现了以下代码,通过

<input type="file" />
选择来解析 CSV:

export async function parse(file: File) {
  let content = '';
  const reader = new FileReader();
  reader.onload = function(e: any) {
    content = e.target.result;
  };
  await reader.readAsText(file);
  const result = content.split(/\r\n|\n/);
  return result;
}

如果我运行此代码并在声明

result
的行上放置一个断点,它将成功检索文件的内容。 如果我不设置任何断点,则内容为空。 正如您所看到的,我将
await
添加到读者以文本形式读取文件的行中,但它仍然不起作用。

javascript html
4个回答
21
投票

await
在这里没有帮助。
readAsText()
不会返回
Promise

您需要将整个过程包装在

Promise
中:

export function parse(file: File) {
  // Always return a Promise
  return new Promise((resolve, reject) => {
    let content = '';
    const reader = new FileReader();
    // Wait till complete
    reader.onloadend = function(e: any) {
      content = e.target.result;
      const result = content.split(/\r\n|\n/);
      resolve(result);
    };
    // Make sure to handle error states
    reader.onerror = function(e: any) {
      reject(e);
    };
    reader.readAsText(file);
  });
}

6
投票

这是我尝试过的JSBin,它的效果非常好。

function parse(file) {
  const reader = new FileReader();
  reader.readAsText(file);
  reader.onload = function(event) {
    // The file's text will be printed here
  console.log(reader.result)
  }
}

更新:

我给你写了一个 Promise 版本。

async function parse(file) {
  const reader = new FileReader();
  reader.readAsText(file);
  const result = await new Promise((resolve, reject) => {
    reader.onload = function(event) {
    resolve(reader.result)
    }
  })
  console.log(result)
}

2
投票

为了稍微概括一下 @zero298 的答案,这里是基于 Promise 的通用包装器

FileReader
-

// get contents of a file as obtained from an html input type=file element
function getFileContents(file) {
  return new Promise((resolve, reject) => {
    let contents = ""
    const reader = new FileReader()
    reader.onloadend = function (e) {
      contents = e.target.result
      resolve(contents)
    }
    reader.onerror = function (e) {
      reject(e)
    }
    reader.readAsText(file)
  })
}

像这样使用-

async function parse(file) {
  const contents = await getFileContents(file)
  const result = contents.split(/\r\n|\n/)
  return result
}

或者在一般情况下,

async function show(file) {
  const contents = await getFileContents(file)
  alert(contents)
}

0
投票

如果您有

FileReader
,则不必再使用
File
File
继承自
Blob
,这意味着您可以使用基于 Promise 的方法:

根据 MDN,截至 2021 年,所有主要浏览器都支持这些。

现在可以编写函数了:

export async function parse(file: File) {
  const content = await file.text();
  const result = content.split(/\r\n|\n/);
  return result;
}
© www.soinside.com 2019 - 2024. All rights reserved.