如何等待 React Native Image Picker 回调函数响应?
How to await for the react native Image Picker callback function response?
我想制作一个功能,将从 react-native-image-picker 中选取的照片上传到 firestore,然后 returns 上传图像的 URL 的值。照片上传成功,我可以在控制台打印下载 URL,问题是当我尝试 return 时,函数中的 URL 是未定义的。我尝试使用异步函数等待图像选择器响应在我 return 它的值之前完成,但它仍然 returns {"_U": 0, "_V": 0, "_W" : 空, "_X": 空}.
uploadImg: async () =>{
await ImagePicker.launchImageLibrary({ mediaType: 'photo' }, response => {
if (response.error) {
alert('Something went wrong');
} else {
try {
const { path, uri } = response;
const fileSource = Platform.OS === 'android' ? uri : path;
const { fileName } = response;
const storageRef = storage().ref(fileName);
storageRef.putFile(fileSource).on('state_changed', snapshot => {
switch (snapshot.state) {
case 'running':
setImageURI(null);
break;
case 'success':
snapshot.ref.getDownloadURL().then(downloadURL => {
setImageURI(downloadURL);
//This console log works, and actually prints the correct url
console.log(`Download URL ${downloadURL}`);
});
break;
default:
break;
}
});
} catch (error) {
console.log(error)
}
}
});
return imageURI;
}
我很确定问题不在于状态、上传图片或图像选择器响应。这可能是异步函数的错误使用。
async/await 的一个非常基本的用法是这样的:
const someCuteAsyncFunc = async () => {
try {
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("done!"), 1000)
});
let result = await promise; // wait until the promise resolves (*)
alert(result); // "done!"
} catch (error) {
console.error(error);
}
}
基于this example.
鉴于您的代码,try/catch、if/else、开关和最后的 return,我认为您需要先简化函数以确保您 return 诺言中的图像。关于这个话题有一个很好的答案 。
这是因为您在 firebase 调用完成执行之前从您的函数返回。我对您的代码进行了一些更新,以便函数可以等待 firebase 响应。
uploadToFirebase: ( fileName, filesource )=>new Promise((resolve, reject)=>{
const storageRef = storage().ref(fileName);
storageRef.putFile(fileSource).on('state_changed', snapshot => {
switch (snapshot.state) {
case 'running':
setImageURI(null);
break;
case 'success':
snapshot.ref.getDownloadURL().then(downloadURL => {
setImageURI(downloadURL);
//This console log works, and actually prints the correct url
console.log(`Download URL ${downloadURL}`);
});
break;
default:
break;
}
resolve();
});
})
uploadImg: async () =>{
let response = await ImagePicker.launchImageLibraryAsync({ mediaType: 'photo' });
if (response.error) {
alert('Something went wrong');
} else {
const { path, uri } = response;
const fileSource = Platform.OS === 'android' ? uri : path;
const { fileName } = response;
await uploadToFirebase(fileName, fileSource)
}
return imageURI;
}
我想制作一个功能,将从 react-native-image-picker 中选取的照片上传到 firestore,然后 returns 上传图像的 URL 的值。照片上传成功,我可以在控制台打印下载 URL,问题是当我尝试 return 时,函数中的 URL 是未定义的。我尝试使用异步函数等待图像选择器响应在我 return 它的值之前完成,但它仍然 returns {"_U": 0, "_V": 0, "_W" : 空, "_X": 空}.
uploadImg: async () =>{
await ImagePicker.launchImageLibrary({ mediaType: 'photo' }, response => {
if (response.error) {
alert('Something went wrong');
} else {
try {
const { path, uri } = response;
const fileSource = Platform.OS === 'android' ? uri : path;
const { fileName } = response;
const storageRef = storage().ref(fileName);
storageRef.putFile(fileSource).on('state_changed', snapshot => {
switch (snapshot.state) {
case 'running':
setImageURI(null);
break;
case 'success':
snapshot.ref.getDownloadURL().then(downloadURL => {
setImageURI(downloadURL);
//This console log works, and actually prints the correct url
console.log(`Download URL ${downloadURL}`);
});
break;
default:
break;
}
});
} catch (error) {
console.log(error)
}
}
});
return imageURI;
}
我很确定问题不在于状态、上传图片或图像选择器响应。这可能是异步函数的错误使用。
async/await 的一个非常基本的用法是这样的:
const someCuteAsyncFunc = async () => {
try {
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("done!"), 1000)
});
let result = await promise; // wait until the promise resolves (*)
alert(result); // "done!"
} catch (error) {
console.error(error);
}
}
基于this example.
鉴于您的代码,try/catch、if/else、开关和最后的 return,我认为您需要先简化函数以确保您 return 诺言中的图像。关于这个话题有一个很好的答案
这是因为您在 firebase 调用完成执行之前从您的函数返回。我对您的代码进行了一些更新,以便函数可以等待 firebase 响应。
uploadToFirebase: ( fileName, filesource )=>new Promise((resolve, reject)=>{
const storageRef = storage().ref(fileName);
storageRef.putFile(fileSource).on('state_changed', snapshot => {
switch (snapshot.state) {
case 'running':
setImageURI(null);
break;
case 'success':
snapshot.ref.getDownloadURL().then(downloadURL => {
setImageURI(downloadURL);
//This console log works, and actually prints the correct url
console.log(`Download URL ${downloadURL}`);
});
break;
default:
break;
}
resolve();
});
})
uploadImg: async () =>{
let response = await ImagePicker.launchImageLibraryAsync({ mediaType: 'photo' });
if (response.error) {
alert('Something went wrong');
} else {
const { path, uri } = response;
const fileSource = Platform.OS === 'android' ? uri : path;
const { fileName } = response;
await uploadToFirebase(fileName, fileSource)
}
return imageURI;
}