我正在使用firebase进行反应,我需要将一些图片上传到firebase存储器,然后保存从上载函数返回的下载网址,以将该值存储在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);
}
};
但是这不起作用,因为控制台首先显示undefined,然后显示url,这意味着await不在等待返回url。我该如何解决?
答案 0 :(得分:2)
问题主要是因为等待,然后一起使用。 通过将代码转换为仅使用await可以有所帮助。
想象一个场景,其中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);
}
}
答案 1 :(得分:1)
我想你在混东西。
如果您正在使用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
实际上是为了使编程以某种“感觉”同步的方式实现。除了代码无法正常工作之外,使用then和callbacks会使它没有从语法中受益。
请参阅https://developer.mozilla.org/fr/docs/Learn/JavaScript/Asynchronous/Concepts