使用异步和等待文件读取器时出错

Posted

技术标签:

【中文标题】使用异步和等待文件读取器时出错【英文标题】:Error using async and await with filereader 【发布时间】:2018-06-18 18:26:11 【问题描述】:

我正在尝试使用 FileReader 读取文件:

async readFile(event: any) 
    var file = event.target.files[0];
    var data:string
    if (file)    
        var reader:FileReader = new FileReader();
         reader.onload = async function (evt : FileReaderEvent) 
            data = await evt.target.result;
            console.log(evt.target.result);

        ;
        console.log(file);
        console.log(data);
        await reader.readAsText(file);
        await this.processFileContent(data);
    
 

但是,evt.target.result 在我的 console.log(file) 调用之后仍然会被打印出来。

有谁知道我如何获取文件的结果并将其传递给我的 processFileContent 函数?

【问题讨论】:

processFileContent 是否期望 File 对象(这是您现在给它的对象)或 string @Touffy 它需要一个字符串 那是你的第一个问题。您正在读取文件,但您并没有将结果保存在任何地方,更不用说将其传递给this.processFileContent 我猜它是先打印的,因为它在等待之前。并且稍后将在事件循环中调用异步内部函数... @Touffy 我更新了代码以便存储结果,但仍有问题 【参考方案1】:

在 blob 本身上使用新的读取方法

/** @type Event evt */
async readFile (evt) 
  const file = evt.target.files[0]
  if (file) 
    const data = await file.text()
    return this.processFileContent(data)
  

【讨论】:

【参考方案2】:

需要利用 reader 将 blob 转换为 base64,更喜欢使用 async-await 语法,所以我选择将 reader 逻辑提取到 helper 中,如下所示:

//* Convert resBlob to base64
export const blobToData = (blob: Blob) => 
  return new Promise((resolve) => 
    const reader = new FileReader()
    reader.onloadend = () => resolve(reader.result)
    reader.readAsDataURL(blob)
  )

并在主代码中使用await 调用它:

//* Convert resBlob to dataUrl and resolve
const resData = await blobToData(resBlob)

【讨论】:

@MartinsOnuoha 虽然没有错误处理。如果您确实实施了它,请随时更新答案。

以上是关于使用异步和等待文件读取器时出错的主要内容,如果未能解决你的问题,请参考以下文章

Windows异步I/O详解

使用流异步读取文件时如何同步处理每一行/缓冲区[重复]

使用 SparkSQL 和 HiveContext 读取 Parquet 文件时出错

无法使用 TSC - 读取文件“anything.ts”时出错:找不到文件

Terraform GCP - 等待设置使用导出存储桶时出错。:“gcp-bucket”需要“读取”权限

读取和写入文件时出错(Java)[关闭]