将值分配给Promise中的对象

问题描述 投票:0回答:1

我的网站上有一个页面,从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
}));
javascript node.js vue.js foreach nuxt
1个回答
0
投票

实际上,这不是应该使用Promises:异步调用项回调的方式。这意味着您需要先返回项目,然后才能在此回调中分配该项目。要在调用方函数中获取promise值,您只需要从promise返回项目并从router.get()函数返回此promise。


0
投票

存在一些Promise使用错误。请勿将async/awaitthen/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
}));
© www.soinside.com 2019 - 2024. All rights reserved.