在继续功能之前等待图像上传的响应
await response of image upload before continue function
所以我正在为一个数组中的多个图像开发一个上传功能。经过一番努力,我终于让我的上传功能正常工作,图像显示在 Firebase 数据库中。但是,我还没有找到一种有效的方法来确保我的上传功能在继续之前完成。
下面是我调用上传函数并尝试将响应存储在上传url中的部分,上传url变量稍后在调度函数中用于存储url 与其他数据。
try {
uploadurl = await uploadImages()
address = await getAddress(selectedLocation)
console.log(uploadurl)
if (!uploadurl.lenght) {
Alert.alert('Upload error', 'Something went wrong uploading the photo, plase try again', [
{ text: 'Okay' }
]);
setIsLoading(true);
return;
}
dispatch(
所以下面是图片上传功能。这适用于上传图像,但是获取下载 URL 的 .then 调用没有正确启动,并且 .then 图像也没有工作。
uploadImages = () => {
const provider = firebase.database().ref(`providers/${uid}`);
let imagesArray = [];
try {
Promise.all(photos)
.then(photoarray => {
console.log('all responses are resolved succesfully')
for (let photo of photoarray) {
let file = photo.data;
const path = "Img_" + uuid.v4();
const ref = firebase
.storage()
.ref(`/${uid}/${path}`);
var metadata = {
contentType: 'image/jpeg',
};
ref.putString(file, 'base64', metadata).then(() => {
ref
.getDownloadURL()
.then(images => {
imagesArray.push({
uri: images
});
console.log("Out-imgArray", imagesArray);
})
})
};
return imagesArray
})
} catch (e) {
console.error(e);
}
};
所以我想return imagesArray,之后所有的照片都上传了。那么 imagesArray 在第一个函数中被设置为 uploadURL ?在 imagesArray 中设置所有图像 URL 并传递给 uploadURL 之后,我上传其余数据的调度函数才应该继续。我怎样才能确保这是按预期发生的?
我现在已经更改了很多次,因为我不断收到不同的方法,以至于我现在完全不知道如何继续:(
您的大部分 uploadImages()
代码都是正确的,但是在许多地方您没有 return 每个异步操作的承诺。
快速回避:处理许多承诺
当处理大量基于数组的异步任务时,建议将数组 map()
转换为 Promises 数组,而不是使用 for 循环。这允许您构建一个可以馈送到 Promise.all() 的承诺数组,而无需初始化并推送到另一个数组。
let arrayOfPromises = someArray.map((entry) => {
// do something with 'entry'
return somePromiseRelatedToEntry();
});
Promise.all(arrayOfPromises)
.then((resultsOfPromises) => {
console.log('All promises resolved successfully');
})
.catch((err) => {
// an error in one of the promises occurred
console.error(err);
})
如果任何包含的承诺失败,上述代码片段将失败。要静默忽略单个错误或将它们推迟到以后处理,您只需在映射数组步骤中添加一个 catch()
。
let arrayOfPromises = someArray.map((entry) => {
// do something with 'entry'
return somePromiseRelatedToEntry()
.catch(err => ({hasError: true, error: err})); // silently ignore errors for processing later
});
已更新 uploadImages()
代码
使用这些更改更新您的代码,得到以下结果:
uploadImages = () => {
const provider = firebase.database().ref(`providers/${uid}`);
// CHANGED: removed 'let imagesArray = [];', no longer needed
return Promise.all(photos) // CHANGED: return the promise chain
.then(photoarray => {
console.log('all responses are resolved successfully');
// take each photo, upload it and then return it's download URL
return Promise.all(photoarray.map((photo) => { // CHANGED: used Promise.all(someArray.map(...)) idiom
let file = photo.data;
const path = "Img_" + uuid.v4();
const storageRef = firebase // CHANGED: renamed 'ref' to 'storageRef'
.storage()
.ref(`/${uid}/${path}`);
let metadata = {
contentType: 'image/jpeg',
};
// upload current photo and get it's download URL
return storageRef.putString(file, 'base64', metadata) // CHANGED: return the promise chain
.then(() => {
console.log(`${path} was uploaded successfully.`);
return storageRef.getDownloadURL() // CHANGED: return the promise chain
.then(fileUrl => ({uri: fileUrl}));
});
}));
})
.then((imagesArray) => { // These lines can
console.log("Out-imgArray: ", imagesArray) // safely be removed.
return imagesArray; // They are just
}) // for logging.
.catch((err) => {
console.error(err);
});
};
所以我正在为一个数组中的多个图像开发一个上传功能。经过一番努力,我终于让我的上传功能正常工作,图像显示在 Firebase 数据库中。但是,我还没有找到一种有效的方法来确保我的上传功能在继续之前完成。
下面是我调用上传函数并尝试将响应存储在上传url中的部分,上传url变量稍后在调度函数中用于存储url 与其他数据。
try {
uploadurl = await uploadImages()
address = await getAddress(selectedLocation)
console.log(uploadurl)
if (!uploadurl.lenght) {
Alert.alert('Upload error', 'Something went wrong uploading the photo, plase try again', [
{ text: 'Okay' }
]);
setIsLoading(true);
return;
}
dispatch(
所以下面是图片上传功能。这适用于上传图像,但是获取下载 URL 的 .then 调用没有正确启动,并且 .then 图像也没有工作。
uploadImages = () => {
const provider = firebase.database().ref(`providers/${uid}`);
let imagesArray = [];
try {
Promise.all(photos)
.then(photoarray => {
console.log('all responses are resolved succesfully')
for (let photo of photoarray) {
let file = photo.data;
const path = "Img_" + uuid.v4();
const ref = firebase
.storage()
.ref(`/${uid}/${path}`);
var metadata = {
contentType: 'image/jpeg',
};
ref.putString(file, 'base64', metadata).then(() => {
ref
.getDownloadURL()
.then(images => {
imagesArray.push({
uri: images
});
console.log("Out-imgArray", imagesArray);
})
})
};
return imagesArray
})
} catch (e) {
console.error(e);
}
};
所以我想return imagesArray,之后所有的照片都上传了。那么 imagesArray 在第一个函数中被设置为 uploadURL ?在 imagesArray 中设置所有图像 URL 并传递给 uploadURL 之后,我上传其余数据的调度函数才应该继续。我怎样才能确保这是按预期发生的?
我现在已经更改了很多次,因为我不断收到不同的方法,以至于我现在完全不知道如何继续:(
您的大部分 uploadImages()
代码都是正确的,但是在许多地方您没有 return 每个异步操作的承诺。
快速回避:处理许多承诺
当处理大量基于数组的异步任务时,建议将数组 map()
转换为 Promises 数组,而不是使用 for 循环。这允许您构建一个可以馈送到 Promise.all() 的承诺数组,而无需初始化并推送到另一个数组。
let arrayOfPromises = someArray.map((entry) => {
// do something with 'entry'
return somePromiseRelatedToEntry();
});
Promise.all(arrayOfPromises)
.then((resultsOfPromises) => {
console.log('All promises resolved successfully');
})
.catch((err) => {
// an error in one of the promises occurred
console.error(err);
})
如果任何包含的承诺失败,上述代码片段将失败。要静默忽略单个错误或将它们推迟到以后处理,您只需在映射数组步骤中添加一个 catch()
。
let arrayOfPromises = someArray.map((entry) => {
// do something with 'entry'
return somePromiseRelatedToEntry()
.catch(err => ({hasError: true, error: err})); // silently ignore errors for processing later
});
已更新 uploadImages()
代码
使用这些更改更新您的代码,得到以下结果:
uploadImages = () => {
const provider = firebase.database().ref(`providers/${uid}`);
// CHANGED: removed 'let imagesArray = [];', no longer needed
return Promise.all(photos) // CHANGED: return the promise chain
.then(photoarray => {
console.log('all responses are resolved successfully');
// take each photo, upload it and then return it's download URL
return Promise.all(photoarray.map((photo) => { // CHANGED: used Promise.all(someArray.map(...)) idiom
let file = photo.data;
const path = "Img_" + uuid.v4();
const storageRef = firebase // CHANGED: renamed 'ref' to 'storageRef'
.storage()
.ref(`/${uid}/${path}`);
let metadata = {
contentType: 'image/jpeg',
};
// upload current photo and get it's download URL
return storageRef.putString(file, 'base64', metadata) // CHANGED: return the promise chain
.then(() => {
console.log(`${path} was uploaded successfully.`);
return storageRef.getDownloadURL() // CHANGED: return the promise chain
.then(fileUrl => ({uri: fileUrl}));
});
}));
})
.then((imagesArray) => { // These lines can
console.log("Out-imgArray: ", imagesArray) // safely be removed.
return imagesArray; // They are just
}) // for logging.
.catch((err) => {
console.error(err);
});
};