节点在一条相互依赖的路由中表达多个查询

时间:2019-03-07 16:44:03

标签: node.js express

一般来说,我只是想熟悉节点,表达和编程,但这是我要解决的一个更复杂的问题。请在这种情况下是否可以提供一些最佳实践。

我试图对我的数据库运行两个查询,其中第一个查询取决于第一个查询的结果。 Q1。返回ID列表。 Q2。返回ID和每个ID的坐标。我想用一个看起来像这样

的json对象来响应
[
  { id: 451, coords: 'POINT(12.5574 43.8351)' },
  { id: 56, coords: 'POINT(13.5574 44.8351)' }
]

当前我无法使其正常工作,我知道示例代码可能存在多个问题,但是我几乎陷入了困境。也许我想得太多了,使它变得比实际更难,或者总体上是不好的做法。 如何运行多个查询,第二个查询使用第一个查询的输出,然后构建正确的对象进行响应。任何指针将不胜感激。

router.get('/asset/:id', (req, res) => {
  let latLngOfAssets = []
  // get associated assets
  function getConnectionsById() {
    queries.getConnectionsById(req.params.id)  // return list of objects
    .then(data => {
      if (data) {
        data.forEach(function(element) {
          getLatLngofAsset(element.til_poi_id)  // for each id in list call function to get coordinate
        });
      } else {
        throw new Error('No data returned');
      }
      console.log(latLngOfAssets) // What I want to respond with res.json(latlngofassets)
    })
  }

  function getLatLngofAsset(id) {
    queries.getPoilatlng(id)  // Return geometry as text for asset with id
    .then(data =>{
      let newassetobj = {}
      if (data) {
        newassetobj["id"] = data.rows[0].id
        newassetobj["coords"] = data.rows[0].st_astext
        //console.log(newassetobj)  // structure of each object { id: 451, coords: 'POINT(12.5574 43.8351)' }
        latLngOfAssets.push(newassetobj) // making list of objects i want to respond with
      } else {
        throw new Error('Did not get any poi');
      }
    })    
  }

  getConnectionsById()

  .catch(err => { // {message: "Cannot read property 'then' of undefined", error: {…}}
    console.error('Something went wrong', err);
  });
});

1 个答案:

答案 0 :(得分:0)

您已经很好地完成了将代码的两个不同部分分离为单独的功能的工作-您缺少的是将它们捆绑在一起的能力。您的代码的这一部分没有执行我认为您要完成的任务:

data.forEach(function(element) {
  getLatLngofAsset(element.til_poi_id)
});

由于getLatLngofAsset()是基于Promise *的,因此您需要像Promise一样使用它。您首先需要使getLatLngofAsset返回它创建的Promise链。然后,可以使用await函数在getConnectionsById内部async编辑:

 function getConnectionsById() {
    queries.getConnectionsById(req.params.id)
    .then(data => {
      if (data) {
        data.forEach(async function(element) { // <-- note the async keyword here
          await getLatLngofAsset(element.til_poi_id)
        });
      } else {
        throw new Error('No data returned');
      }
      console.log(latLngOfAssets) // What I want to respond with res.json(latlngofassets)
    })
  }

这是一个开始-一旦了解了已声明的函数与它们创建并返回的Promise之间的关系,我们还可以解决另外两件事。