此问题在此处已有答案:
How can I access the value of a promise?(共14个答案)
How do I return the response from an asynchronous call?(44个答案)
两个月前关门了。
我需要返回getThumbnail
函数来调整图片的大小。现在的问题是当我尝试下面的代码时,所有分配给dispatch的有效负载现在都返回一个promise。我如何摆脱这个问题,只返回一个普通的有效负载。以前我没有getThumbnail
也可以返回它,但现在我被迫返回它,因为getThumbnail
是一个promise。我如何修复这个问题?我应该调整getThumbnail
函数还是?
关于这个问题的代码:
const responseImages = response?.data?.map(async (image) => {
return {
productName: image?.uploadResult?.productTitle,
imageFile: await getThumbnail(
images.find((img) => img?.imageFileName === image?.mediaCode)
?.imageFile || null, {
thumbWidth: 100,
thumbHeight: 100,
bgColor: "black",
}
),
imageFileName: image?.mediaCode || "",
};
});
助手.js
const loadImage = (src) =>
new Promise((resolve, reject) => {
const img = new Image()
img.onload = () => resolve(img)
img.onerror = reject
img.src = src
})
const resize = (imageWidth, imageHeight, thumbWidth, thumbHeight) => {
let w = 0,
h = 0,
x = 0,
y = 0,
widthratio = imageWidth / thumbWidth,
heightratio = imageHeight / thumbHeight,
maxratio = Math.max(widthratio, heightratio)
if (maxratio > 1) {
w = imageWidth / maxratio
h = imageHeight / maxratio
} else {
w = imageWidth
h = imageHeight
}
x = (thumbWidth - w) / 2
y = (thumbHeight - h) / 2
return { w: w, h: h, x: x, y: y }
}
export async function getThumbnail(
photo,
{ thumbWidth, thumbHeight, bgColor }
) {
const img = await loadImage(URL.createObjectURL(photo))
const { naturalWidth, naturalHeight } = img
const canvas = document.createElement('canvas')
const cx = canvas.getContext('2d')
canvas.width = thumbWidth
canvas.height = thumbHeight
const dimensions = resize(
naturalWidth,
naturalHeight,
thumbWidth,
thumbHeight
)
cx.fillStyle = bgColor
cx.fillRect(0, 0, thumbWidth, thumbHeight)
cx.drawImage(img, dimensions.x, dimensions.y, dimensions.w, dimensions.h)
return canvas.toDataURL('image/jpeg')
}
操作.js
export const uploadPhotos =
({
photos,
size,
controller
}) =>
async (dispatch) => {
// Identify the part of the file name that excludes the (optional) sequence number
const keyedphotos = photos.map((photo) => [
photo.imageFileName.replace(/-\w+\.\w+$/, ""),
photo,
]);
// Create a group for each such prefix
const map = new Map(keyedphotos.map(([key]) => [key, []]));
// Populate those groups
for (const [key, photo] of keyedphotos) map.get(key).push(photo);
// And extract those groups into an array (of subarrays)
const photoGroups = [...map.values()];
let index = 0; // Keep the index counter separate
photoGroups.forEach(async (photos) => {
// Iterate the groups that can run in parallel
for (const photo of photos) {
// Iterate the photos that should run sequentially
const id = index++; // Get the next unique id
const formData = new FormData();
formData.append(photo?.imageFileName, photo?.imageFile);
dispatch({
type: constants.UPLOAD_PHOTOS_START,
size
});
try {
const response = await axios.post(
`${API_URL}/photos/upload`,
formData, {
onUploadProgress({
loaded,
total
}) {
dispatch(setUploadProgress({
id,
loaded,
total
})); // Use id
},
signal: controller.signal,
}
);
dispatch({
type: constants.UPLOAD_PHOTOS_SUCCESS,
payload: response.data,
});
const responseImages = response?.data?.map(async (image) => {
return {
productName: image?.uploadResult?.productTitle,
imageFile: await getThumbnail(
images.find((img) => img?.imageFileName === image?.mediaCode)
?.imageFile || null, {
thumbWidth: 100,
thumbHeight: 100,
bgColor: "black",
}
),
imageFileName: image?.mediaCode || "",
};
});
} catch (error) {
dispatch({
type: constants.UPLOAD_PHOTOS_FAILURE,
payload: error,
});
}
}
});
};
1条答案
按热度按时间bvpmtnay1#
我假设您的
response.data
确实是一个数组,因此您可以使用map
函数。这里,问题福尔斯在您为
map
提供的函数上。async...await
函数实际上返回的是Promise
,而不是已解析的对象。因此,对于
data
中的每一项,您得到的是“解析数据的承诺,而不是数据本身”。幸运的是,你只差一步就能实现你的愿望。
只需将代码封装到
Promise.all()
中,因为all(...)
接受一个Promises数组,并返回解析后的数据。最后,根据具体情况,您可以考虑
Promise.allSettled()
、Promise.any()
、Promise.race()
。阅读有关这些标准函数/方法的更多信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise