router.get('/', function (req, res, next) {
var size = req.params.size ? parseInt(req.params.size) : 20;
var page = req.params.page ? req.params.page>0 ? (size&(parseInt(req.params.page)-1)) : 0 : 0;
db.knex.select('t.id', 't.title', 't.slug', 't.start_date', 't.end_date', 't.enable_date', 't.disable_date', 't.featured', 't.category', 't.status')
.from('tournament AS t')
.limit(size).offset(page)
.then(result => {
let arr = [];
arr = result.map(x => {
db.knex.select('td.id', 'td.d_title')
.from('tournament_detail as td')
.where('td.tournament_id', x.id)
.asCallback((err, row) => {
if(err) return console.error(err);
x['detail'] = row;
console.log(x);
return x;
});
})
}).catch(err => {
console.log(err);
res.send(err)
})
});
此代码产生的结果显示在图像中,但我希望将这些对象合并到数组中。
我如何实现它?
请帮助。
答案 0 :(得分:1)
我认为您遇到的问题是您正在使用result.map
,它不会等待promise解析,然后您正在使用基于promise的knex查询。取而代之的是,您需要使用一个映射函数来等待promise的执行。如果您在节点8或更高版本上,则应该可以使用本机Promise.all
,如果您使用的是较低版本,则建议尝试Bluebird library。这样会将您的代码更改为如下所示。
var Bluebird = require('bluebird');
router.get('/', function (req, res, next) {
var size = req.params.size ? parseInt(req.params.size) : 20;
var page = req.params.page ? req.params.page>0 ? (size&(parseInt(req.params.page)-1)) : 0 : 0;
db.knex.select('t.id', 't.title', 't.slug', 't.start_date', 't.end_date', 't.enable_date', 't.disable_date', 't.featured', 't.category', 't.status')
.from('tournament AS t')
.limit(size).offset(page)
.then(result => {
return Bluebird.map(result, x => {
return db.knex.select('td.id', 'td.d_title')
.from('tournament_detail as td')
.where('td.tournament_id', x.id);
});
}).then((arr) => {
console.log(arr);
})
.catch(err => {
console.log(err);
res.send(err)
})
});
在上面,我们使用Bluebird.map遍历结果,对它们执行knex promises以检索第二个数据集。最后,arr
值将是地图查询结果的集合。
使用本地Promise.all
很相似,只需将Bluebird.map
替换为Promise.all
,就可以了。
顺便说一句,如果您使用的是nodejs 8或更高版本,则还可以使用async / await使此代码更好。这样,您可以保留results.map
并使用异步功能。
警告,我尚未运行此代码,因此它可能存在一些语法错误等。但是,您要使用Bluebird.map。