我正在尝试学习正确使用异步等待,但是对此我感到有些困惑。
在代码片段中,我试图构建一个对象数组,其中包含我需要在组件中上传的文件的相关信息。问题是this.fileInfo中的对象没有完全等待诺言返回编码的图像,而是在我console.log this.fileInfo:
时返回此输出。如您所见,关键图像是一个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);
};
}
答案 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
后缀。
修改