【问题标题】:Javascript - get value from FileReader asynchronous onload methodJavascript - 从 FileReader 异步 onload 方法获取值
【发布时间】:2023-12-17 16:30:01
【问题描述】:

我知道这个问题在这里被问过很多次,但我查看了这些答案,但无法让我的代码正常工作。我正在使用 Angular 2。 我有用于文件插入的输入标签。文件进入组件,但是当我将其转换为数组缓冲区并尝试将其设置为变量时,我的变量仍未定义。我试图实现回调,但我认为我做错了。

这是我的代码:

addPlayer() {
    var nationality = document.getElementById("nationality") as HTMLSelectElement;
    var position = document.getElementById("position") as HTMLSelectElement;
    var shirtnmbr = document.getElementById("shirtnmbr") as HTMLSelectElement;
    var profilePicture = document.getElementById("profilepic") as HTMLSelectElement;
    var inGamePicture = document.getElementById("detailspic") as HTMLSelectElement;
    var player = {
        Club_ID: this.clubId,
        Name: this.capitalization(this.addForm.get("name").value),
        Surname: this.capitalization(this.addForm.get("surname").value),
        Height: this.addForm.get("height").value,
        Weight: this.addForm.get("weight").value,
        BirthDate: this.addForm.get("birthdate").value.formatted,
        Nationality: this.nationalities[nationality.selectedIndex],
        Position: this.order[position.selectedIndex],
        Shirtnmbr: this.shirtNumbers[shirtnmbr.selectedIndex],
        ProfilePicture: this.conversion(profilePicture, function (res) {
            return res;
        }),
        InGamePicture: this.conversion(inGamePicture, function (res) {
            return res;
        })
    };
    console.log(player);  
}

capitalization(str) {
    return str.replace(/\w\S*/g, function (txt) { return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); });
}

conversion(element, callback) {
    var file = element.files;
    var result;
    var fileReader = new FileReader();
    fileReader.onload = function () {
        result = fileReader.result;
        callback(result);
    };
    fileReader.readAsArrayBuffer(file[0]);
}

当我记录播放器时,除了 ProfilePicture 和 InGamePicture(它们是未定义的)之外,每个属性都有值。之后我打算将该玩家发送到数据库,但目前我不能这样做,因为 http.post 会在 ProfilePicture 和 InGamePicture 属性获取值之前运行。

【问题讨论】:

  • 您需要确保两个回调都已完成,然后再将数据发送到我假设的 HTTP?也只是一个建议,你应该使用 Promise 或者因为使用 Angular 2 那么你应该使用 RXJS 而不是回调。
  • @LiverpoolOwen 你能举个例子吗?

标签: javascript angular filereader


【解决方案1】:

您将 ProfilePictureInGamePicture 设置为等于 conversion() 的返回值的值,它永远不会返回任何内容,因此它们将始终为 undefined。你给了一个你调用的回调,但它实际上什么也没做(返回从未处理过的参数)。

在继续之前,您需要同步完成两个FileReader 操作。如果您只能异步获取结果,那么这听起来像是 Promises 的工作,这是当今处理具有多个异步操作的控制流的首选方式。

【讨论】:

  • 不,不是吗?它设置了一个调用回调的onload,它只返回给定的参数,然后立即丢弃结果(callback(result) 表达式只是运行而不存储,因此它的返回值将被丢弃)。这一切都是异步的。 onload 设置不会阻塞程序流程,函数将立即返回(返回值 undefined)。
  • 这正是我面临的问题。不知道怎么解决。
  • 如我所说,无需深入研究,将控制流重构为承诺可能会实现您想要的。有关类似问题,请参阅 *.com/questions/34495796/…
  • 我在看那个例子,但我不明白它是如何工作的。确切地说,我不知道如何在我的代码中实现承诺。
  • @jlaitio 你能告诉我如何存储回调(结果)以从该函数获取返回值吗?我不熟悉承诺。