pg-promise 解决映射函数中的多个查询
pg-promise resolving multiple queries in a map function
与 相关,我现在正尝试 return 从地图函数中进行多个查询
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 = #`, id)
const itemDetails = items.map(async item => {
const layers = await t.any(`SELECT l.* FROM layer l WHERE l.item_id = #`, item.id)
const bases = await t.any(`SELECT b.* FROM base b WHERE b.item_id = #`, 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}
})
}
但是,我不确定如何正确解决多个查询(图层和基础)。如果我正在 returning 一个或另一个,根据链接的问题,我可以在继续之前批量解决承诺数组。但是,当 return 在每次地图迭代中查询多个查询时,我不确定如何在继续之前正确解决所有问题。
您做的一些事情有些奇怪。这是更正后的版本:
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 控制器混合。
谢谢!所以为了完全分离关注点,我应该做类似的事情:
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};
})
然后当我调用这个函数时,说把它添加到 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)
})
与
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 = #`, id)
const itemDetails = items.map(async item => {
const layers = await t.any(`SELECT l.* FROM layer l WHERE l.item_id = #`, item.id)
const bases = await t.any(`SELECT b.* FROM base b WHERE b.item_id = #`, 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}
})
}
但是,我不确定如何正确解决多个查询(图层和基础)。如果我正在 returning 一个或另一个,根据链接的问题,我可以在继续之前批量解决承诺数组。但是,当 return 在每次地图迭代中查询多个查询时,我不确定如何在继续之前正确解决所有问题。
您做的一些事情有些奇怪。这是更正后的版本:
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 控制器混合。
谢谢!所以为了完全分离关注点,我应该做类似的事情:
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};
})
然后当我调用这个函数时,说把它添加到 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)
})