繁体   English   中英

await FileReader.readAsDataURL(fileIn) 在继续之前不等待结果

[英]await FileReader.readAsDataURL(fileIn) doesn't wait for the result before moving on

我正在处理一段代码,其中用户使用 a 输入图像,基本上就像用于更改个人资料图片的内容一样。 我的问题是,当我尝试使用 FileReader() 读取文件时,程序不会在调用需要结果的函数之前返回到 onloadend。 事实上,它只是在我的 fetch 得到响应后才返回。 据我所知,我已经尝试过异步/等待、回调和一些粗略的迂回方法,但到目前为止没有任何效果。

我的转换 function 如下所示:

async function getB64StringFromFile(fileIn) {
    var reader = new FileReader();

    reader.onloadend = function () {
        return reader.result;
    }

    if (fileIn && (fileIn.type == "image/jpeg" || fileIn.type == "image/png" && fileIn.size < 1 * Math.pow(2, 20))) {
        await reader.readAsDataURL(fileIn);
    } else {
        console.log("bad");
    }
}

我的主要 function 看起来有点像这样:

async function updateBook(ev) {
    var form = ev.target.closest("form");
    var data = new FormData(form);

    /*long section of code that is irrelevant to the problem*/
    var objectData = Object.fromEntries(data);

    //the image as a file -- which already proved to be working
    let file = document.querySelector('input[type=file]#imageInput').files[0];

    if (file) {
        objectData.ImageB64String = await getB64StringFromFile(file);
    }

    fetch("/inventory/update/", {
        method: "POST",
        contentType: "application/json; charset=utf-8",
        body: JSON.stringify(objectData),
        headers: {
            "Content-Type": "application/json",
            "RequestVerificationToken": csrfToken,
        },
    }).then((res) => { ... })
}

这里的大问题是射击顺序是

  1. 更新书()
  2. 调用 getB64StringFromFile()
  3. 拿来
  4. 来自 controller 的回复——这很糟糕,因为它没有随附 Base64String
  5. 返回到 onloadend 并返回 String

我想要的是

  1. 更新书()
  2. 调用 getB64StringFromFile()
  3. 等待 onloadend 准备好
  4. Go 回到onloadend,得到结果
  5. 拿来

我很乐意帮助,我已经在这里工作了 9 个小时。 可能缺少等待或无用/放错地方的等待,但我一路上尝试了很多东西,以至于我忘记了什么是正确的。

编辑:我尝试使用 PromiseApi,但它仍然没有等待,而是像以前一样继续前进,而 promise 被限定为“待定”。

Promise 的新代码:

function getB64StringFromFile(fileIn) {
    return new Promise(function (fulfilled, rejected) {
        var reader = new FileReader();
        var string;

        reader.onloadend = function () {
            string = reader.result;
            fulfilled(string); 
        }

        if (fileIn && (fileIn.type == "image/jpeg" || fileIn.type == "image/png" && fileIn.size < 1 * Math.pow(2, 20))) {
            reader.readAsDataURL(fileIn);
        } else {
            console.log("bad");
        }
    })
}

也许我没有正确使用 Promise,我不知道。

这会代替您当前的事件处理程序吗?

reader.addEventListener("load", () => {
    fulfilled(reader.result);
  }, false);

此外,如果fileIn无效,而不是控制台日志记录,您应该调用rejected() 这对于getB64StringFromFile()的调用者来说更有意义。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM