[英]await not waiting for async function to return value
我正在使用与 firebase 的反应,我需要将一些图片上传到 firebase 存储,然后保存从上传函数返回的下载 url 以将该值存储在 firestore 上。
这是我的图片上传功能
const imageUpload = async (image) => { const uploadTask = storage.ref(`images/${image.name}`).put(image); uploadTask.on( 'state_changed', (snapshot) => {}, (error) => { console.log(error); }, () => { storage .ref('images') .child(image.name) .getDownloadURL() .then((url) => { setImageUrl(url); console.log(url); return url; }); } ); };
这是我的提交处理程序
const handleSubmit = async (e) => { e.preventDefault(); let entry = { author: currentUser.email, body, }; if (image) { await imageUpload(image).then(async (url) => { console.log(url); entry = { author: currentUser.email, body, imageUrl, }; try { await createEntry(entry).then(() => { setBody(''); setShowSnackbar(true); }); } catch (error) { console.log(error); } }); } try { await createEntry(entry).then(() => { setBody(''); setShowSnackbar(true); }); } catch (error) { console.log(error); } };
但是,这不起作用,因为控制台首先显示未定义,然后显示 url,这意味着 await 不等待返回 url。 我如何解决这个问题?
问题主要是因为await然后一起使用。 通过将您的代码转换为使用 await only 可以提供帮助。
想象一下,一个地方的场景function c
时,称为function a
一个异步调用function b
做出决议:
const a = () => {
b().then(() => c());
};
这是相同的程序,使用 async/await 而不是 promise 编写:
const a = async () => {
await b();
c();
};
所以你的图片上传逻辑看起来像下面的代码,你可以转换其余的代码:
const url = await imageUpload(image)
console.log(url);
entry = {
author: currentUser.email,
body,
imageUrl,
};
imageUpload 函数看起来像,
async function imageUpload(image) {
try {
const storageRef = firebase.storage().ref();
// Create the file metadata
const metadata = { contentType: "image/jpeg" };
const fileRef = storageRef.child(`${this.name}/` + image.name);
const uploadTaskSnapshot = await fileRef.put(file, metadata);
const downloadURL = await uploadTaskSnapshot.ref.getDownloadURL();
setImageUrl(url);
console.log(url);
return downloadURL;
} catch (error) {
console.log("ERR ===", error);
}
}
我认为你在混合东西。
如果您使用 async / await,则不需要在您的承诺中使用 then
使用 async/await 习惯用法,您的代码应该看起来更像
async function handleSubmit(e) {
e.preventDefault();
let entry = {
author: currentUser.email,
body,
};
if (image) {
const url = await imageUpload(image);
entry = {
author: currentUser.email,
body,
imageUrl,
};
try {
await createEntry(entry);
setBody("");
setShowSnackbar(true);
} catch (error) {
console.log(error);
}
}
try {
await createEntry(entry);
setBody("");
setShowSnackbar(true);
} catch (error) {
console.log(error);
}
}
async function imageUpload(image) {
const uploadTask = storage.ref(`images/${image.name}`).put(image);
return new Promise((resolve, reject) => {
uploadTask.on(
"state_changed",
(snapshot) => {},
(error) => {
reject(error);
},
() => {
storage
.ref("images")
.child(image.name)
.getDownloadURL()
.then((url) => {
setImageUrl(url);
resolve(url);
});
}
);
});
}
async/await
实际上是为了让带有 Promise 的编程以某种方式“感觉”同步。 使用 then 和回调,除了代码不起作用的事实之外,使它无法从语法中受益。
见https://developer.mozilla.org/fr/docs/Learn/JavaScript/Asynchronous/Concepts
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.