为什么等待诺言不等待诺言解决?

时间:2018-11-27 17:04:50

标签: javascript angular async-await

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

在代码片段中,我试图构建一个对象数组,其中包含我需要在组件中上传的文件的相关信息。问题是this.fileInfo中的对象没有完全等待诺言返回编码的图像,而是在我console.log this.fileInfo:

时返回此输出。

output

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

函数build()

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);
    };
}

1 个答案:

答案 0 :(得分:3)

此功能async previewFile(file)中您什么都没有等待。 也许您假设在代码行中的某个地方返回一个新的Promise会使它作为Promise起作用。在这种特殊情况下,它将不起作用,因为它位于委托(加载)内部,因此不会在函数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...
    }
}

当然,您可以执行一系列的promise,以实现某种程度的并发,但这将帮助您入门。

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

修改

Stackblitz example of async logic