我正在学习异步/等待,但是我真的不知道这里出了什么问题。为什么我在使用myArray
时总是空着?我该如何解决?
function getFileAsBinary(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsBinaryString(file);
reader.onload = () => resolve(reader.result);
reader.onerror = (error) => reject(error);
});
};
const preparePhotos = async (photoFiles, myArray) => {
photoFiles.forEach(async (photoFile) => {
const photoBinary = await getFileAsBinary(photoFile);
myArray.push("something")
});
}
// ----------------------------------------------------
const myArray= [];
const photos = [file1,file2];
await preparePhotos(photos,myArray);
console.log(myArray); // getting [] here, why is it empty?
答案 0 :(得分:2)
传递给forEach的回调不是同步的,它可以工作,但不能达到预期。迭代完成后,异步函数“ preparePhotos”将立即返回。
我认为您应该改用for循环。
PD:我不知道这个问题是否重复了Using async/await with a forEach loop
答案 1 :(得分:1)
在forEach循环中使用await时,是在告诉js引擎在lambda而不是整个函数中“等待”。
如果您希望能够等待preparePhotos函数,则需要一些如何从lambda中“等待”。
首先定义一个诺言
let promises = [];
然后,不要等待getFileAsBinary返回的诺言,而是将其追加到列表中
photoFiles.forEach((photoFile) => {
promises.push(getFileAsBinary(photoFile));
})
您现在有了一个诺言列表,可以使用Promise.all等待列表中的所有诺言
let myArray = await Promise.all(promises);
Promise#all返回由原始数组中的promise解析的所有值的列表,因此它将有效地返回原始的“ myArray”。
或者,使用for循环(MDN:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of)
for(let elem of photoFiles) {
let binary = await getFileAsBinary(elem);
myArray.push(binary);
}