操作Promise返回的对象和数组

时间:2018-07-31 07:03:51

标签: javascript arrays express object promise

enter image description here

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

此代码产生的结果显示在图像中,但我希望将这些对象合并到数组中。

我如何实现它?

请帮助。

我的预期输出是这样的 enter image description here

1 个答案:

答案 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。