【问题标题】:Angular 8: not able to access a class variable which is set inside FileReader onloadend methodAngular 8:无法访问在 FileReader onloadend 方法中设置的类变量
【发布时间】:2020-04-20 20:33:45
【问题描述】:

我无法访问在 FileReader onloadend 方法中设置的类变量。

这是我的代码:

analyzeData(){
let file = this.fileRestful[0];
let fileReader: FileReader = new FileReader();
fileReader.onloadend = () => {
  this.fileContent= fileReader.result as string;
}
fileReader.readAsText(file);
console.log(this.fileContent)

}

到目前为止,我已经尝试了 3 种方法,但都没有奏效。以下是他们:

  1. fileReader.onloadend = () => { this.fileContent= fileReader.result as string; }
  2. fileReader.onloadend = function(e) = { this.fileContent= fileReader.result as string; }.bind(this)

  3. let self = this; fileReader.onloadend = function(e) = { self.fileContent= fileReader.result as string; }

我已经看到了大部分解决方案,但没有一个对我有用。 请让我知道我在哪里出错。谢谢。

【问题讨论】:

    标签: angular


    【解决方案1】:

    我不认为这里的问题是由this 关键字引起的。您的 this 指向正确的位置,但没有分配给 this.fileContent 变量。

    this.fileContent 设置在 asynchronous block of code 中。你的赋值会在你的console.log之后执行,因为fileReader.onloadend只是一个监听器,类似于DOM中的onclick监听器。

    fileReader.onloadend = () => {
      this.fileContent= fileReader.result as string; // this code will be executed some time in the future
    }
    fileReader.readAsText(file);
    console.log(this.fileContent); // this code will be executed first
    

    换句话说,在第一行中,您向loadend 事件添加了一个事件侦听器。您的箭头函数将在 loadend 发生时执行,而不是立即执行。什么时候会发生 - 我们不知道,可能在三年内,可能在 0.0002 秒内,但肯定是在您的其余代码执行之后。

    解决方案

    当您将console.log 移至代码的异步部分时,您的console.log 将反映现实情况,如下所示:

    fileReader.onloadend = () => {
      this.fileContent= fileReader.result as string; // this code will be executed some time in the future
      console.log(this.fileContent); // and after that you do your console.log
    
    }
    fileReader.readAsText(file);
    

    setTimeouton* 处理程序、addEventListener 中的代码是我们需要始终记住代码执行时间的示例。它可以在同步代码后三秒或三年执行。 我建议阅读is this section on MDN 的规范资源。很多,但是为了写js代码,理解是必不可少的。

    【讨论】:

    • 嗨@ganqqwery:正如你提到的console.log(this.fileContent);总是打印它。我的问题是,即使我等待,我也无法在 onloadend 函数之外访问 fileContent。
    • 无法在onloadend 函数之外访问fileContent,因为javascript 引擎不会等到onloadend 完成。 onloadend函数声明之后的代码将在onloadend函数之后执行。
    • 我的意思是:stackblitz.com/edit/angular-file-read。在这里您可以访问它。我可能错了。但这对我不起作用。
    • 情况有所不同。在 Angular Core 中有一个异步无限循环,它始终检查模板中变量的值是否已更改,这称为更改检测。这就是它向您显示内容的原因。想象一下,你的 console.log 里面有永无止境的 setInterval 并且它不断地打印值。
    • 好的。那么我现在有什么选择呢?我想获取 fileContent 并调用另一个对象在类构造函数中的 REST api。但是当我在 onloaded 函数中使用带有“this”的 REST 服务时,它总是为 null。
    猜你喜欢
    • 2015-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-08
    相关资源
    最近更新 更多