我的网站上有一个页面,从Firebase Cloud Firestore检索1个项目。这个网站是用Vue.js和Nuxt.js建立的。我通过我和我的朋友使用Express.js制作的API来获得该项目。在页面上有一个带有图像的画廊,我想使用软件包Photoswipe
来刷过图像,但是我需要图像尺寸。由于我将文档保存到Firebase时无法设置尺寸,因此我尝试在API中接收项目时获取图像尺寸。我正在尝试通过遍历所有图库图像的foreach循环中使用包probe-image-size
来实现此目的。
我的问题是,我似乎无法从data
承诺的内部为.then()
对象设置尺寸值。
我已经尝试过从诺言中返回值,但这似乎对我不起作用。
这是用于获取特定项目的API端点:
router.get('/:id', api(async req => {
let item = null
await collection.doc(req.params.id).get().then((doc) => {
if (doc.exists) {
const data = doc.data()
data.images.forEach(function (image) {
probe(image.url).then(res => {
image.width = res.width;
image.height = res.height;
})
});
console.log(data.images);
//delete data.createdBy
item = data
}
}).catch((error) => {
console.error(`Error getting project ${req.params.id}:`, error);
})
return item
}));
实际上,这不是应该使用Promises:异步调用项回调的方式。这意味着您需要先返回项目,然后才能在此回调中分配该项目。要在调用方函数中获取promise值,您只需要从promise返回项目并从router.get()
函数返回此promise。
存在一些Promise使用错误。请勿将async/await
与then/catch
混合使用,至少不要在被迫时混合使用。
array.foreach()
不等待承诺,而是不做任何其他事情就启动它们。一种解决方案是map
所有承诺,然后等待它们。
router.get('/:id', api(async req => {
let item, doc = null
try {
doc = await collection.doc(req.params.id).get()
} catch (err) {
console.error(`Error getting project ${req.params.id}:`, error);
}
if (doc && doc.exists) {
const data = doc.data()
probe_promises = data.images.map(image => probe(image.url).then(res => {
image.width = res.width;
image.height = res.height;
}))
await Promise.all(probe_promises)
console.log(data.images);
item = data
}
return item
}));