FileReader readAsText()异步问题?

时间:2018-06-25 14:56:29

标签: javascript html

我已实现以下代码,以通过<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,但是仍然无法正常工作。

3 个答案:

答案 0 :(得分:5)

await在这里没有帮助。 readAsText() doesn't return a 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);
  });
}

答案 1 :(得分:0)

这是我尝试过的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 :(得分:0)

要稍微推广@ zero298的答案,以下是FileReader-

周围基于Promise的通用包装器
// 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)
}