簡體   English   中英

pg-promise 解決 map function 中的多個查詢

[英]pg-promise resolving multiple queries in a map function

forEach 循環中的相關查詢相關的 pg-promise 事務給出警告錯誤:查詢已釋放或丟失的連接,我現在正嘗試從 map function 中返回多個查詢

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}
    })
}

但是,我不確定如何正確解決多個查詢(層和基礎)。 如果我返回一個或另一個,根據鏈接的問題,我可以在繼續之前批量解決一系列承諾。 但是,當在每個 map 迭代中返回多個查詢時,我不確定如何在繼續之前正確解決所有問題。

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

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 function 之外,即避免將數據庫邏輯與 HTTP 控制器混合。

謝謝,所以要完全分開關注點:我應該做類似的事情:

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};
    })

然后當我調用這個 function 時,說要將它添加到express api,做

  router.get('/:id', async (req, res, next) => {
    const all = await get(req.params.id)
      .then(data => {
        return {success: true, response: data}
      })
      .catch(error => {
        return {success: false, response: error.message || error}
      })
    res.json(all)
  })

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM