首页 > 解决方案 > pg-promise 解决 map 函数中的多个查询

问题描述

pg-promise 事务相关,在 forEach 循环中具有依赖查询会给出警告错误:查询已释放或丢失的连接,我现在正尝试从映射函数中返回多个查询

const {db} = require('../db')

async function get(id) {
  return await db
    .task(async t => {
      const items = await t.any(`SELECT i.* FROM item i WHERE i.parent_id = $1#`, id)
      const itemDetails = items.map(async item => {
        const layers = await t.any(`SELECT l.* FROM layer l WHERE l.item_id = $1#`, item.id)
        const bases = await t.any(`SELECT b.* FROM base b WHERE b.item_id = $1#`, item.id)
        return [layers, bases]
      })
      // Not resolving properly!
      await t.batch(itemDetails.flat())

      return {items: items, itemDetails: itemDetails}
    })
    .then(data => {
      return {success: true, response: data}
    })
    .catch(error => {
      return {success: false, response: error.message || error}
    })
}

但是,我不确定如何正确解决多个查询(层和基础)。如果我返回一个或另一个,根据链接的问题,我可以在继续之前批量解决一系列承诺。但是,在每次地图迭代中返回多个查询时,我不确定如何在继续之前正确解决所有问题。

标签: node.jspostgresqlpg-promise

解决方案


您正在以一种奇怪的方式做一些事情。这是修正版:

function get(id) {
  return db.task(async t => {
      const items = await t.any(`SELECT i.* FROM item i WHERE i.parent_id = $<id>`, {id});
      const itemDetails = items.map(async item => {
        const layers = await t.any(`SELECT l.* FROM layer l WHERE l.item_id = $<id>`, item);
        const bases = await t.any(`SELECT b.* FROM base b WHERE b.item_id = $<id>`, item);
        return {layers, bases};
      });

      const details = await t.batch(itemDetails);

      return {items, details};
    })
    .then(data => {
      return {success: true, response: data};
    })
    .catch(error => {
      return {success: false, response: error.message || error};
    })
}

请注意,您仍然会在这里混合关注,因为.then->.catch应该在get此处的功能之外,即避免将数据库逻辑与 HTTP 控制器混合。


推荐阅读