【问题标题】:Why await a promise doesn't wait the promise to resolve?为什么等待承诺不等待承诺解决?
【发布时间】:2019-04-29 11:44:31
【问题描述】:

我正在尝试学习正确使用异步等待,但我对此感到有些困惑。

在 sn-ps 中,我正在尝试构建一个对象数组,其中包含我在组件中上传的文件所需的信息。问题是 this.fileInfo 中的对象并没有完全等待返回编码图像的承诺,而是在我 console.log this.fileInfo 时返回此输出:

如您所见,关键图像是一个 ZoneAwarePromise,其值未定义。你能帮我解决这个问题吗?

函数构建()

async build(e) {
    let files = e.target.files;
    this.j = Array.from(files);
    this.fileInfo = await this.j.reduce((acc, cur) => [
        ...acc, {
            name: cur.name.replace(/^.*\\/, ""),
            sizeunit: this.getSize(cur.size),
            extention: cur.name.split(/\.(?=[^\.]+$)/).slice(-1).pop().toString(),
            image: this.previewFile(cur)
        }
    ], [])
    console.log(await this.fileInfo);
}

承诺

async previewFile(file) {

    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => {
        return new Promise((res) => {
            res(reader.result)
        }).then( res => res);
    };
}

【问题讨论】:

  • 但是 .then 附加到承诺不应该返回值?
  • 我也试过 image: await this.previewFile(cur) 但它返回错误 ''TS1308: 'await' 表达式只允许在异步函数中。'' :/

标签: javascript angular async-await


【解决方案1】:

您不会在此函数中等待任何内容:async previewFile(file)。 也许你假设在你的代码行中的某个地方返回一个新的 Promise 会使它作为一个 Promise 运行。在这种特殊情况下,它将不起作用,因为它位于委托(onload)内部,不会在您的函数previewFile() 范围内执行。

你可以失去 async 修饰符,因为你可以返回一个 Promise 来代替:

previewFileAsync(file) {
    // the async modifier keyword is not necessary,
    // because we don't need to await anything.
    return new Promise((res) => {
         const reader = new FileReader();
         reader.readAsDataURL(file);
         reader.onload = () => res(reader.result);
    });
}

当你调用它时,你可以在循环中等待它:

async buildAsync(e) {
    let files = e.target.files;
    for(let i = 0; i < files.length; i++) {
        const file = files[i];
        const preview = await previewFileAsync(file);
        // Do something with preview here...
    }
}

当然,您可以执行一系列承诺以允许某种并发,但这将帮助您入门。

我在您的方法中添加了Async 后缀,以便调用者知道可以等待。它没有做任何特别的事情,但它有助于澄清您的代码。您可以使用任何您认为正确的后缀。我只是习惯了Async后缀。

编辑

Stackblitz example of async logic

【讨论】:

  • 非常感谢,这很有效,但我需要澄清一下:你能解释一下为什么 onload 不会在函数 previewFile() 的范围内执行吗?
  • @NadG 我添加了一个 stackblitz 示例,用代码解释了它是如何工作的。
  • 非常感谢您的宝贵时间,现在非常清楚了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-04
  • 2021-11-09
  • 2014-03-12
相关资源
最近更新 更多