Node js - 用于返回从sequelize数据库读取的对象数组的函数

时间:2018-05-30 05:35:12

标签: javascript node.js sequelize.js

我试图在节点js中创建一个函数,它读入数据库值并将它们推入一个数组,然后在最后返回这个数组。我的功能目前看起来像这样:

function getInvoicesCount() {
      let promiseInvoices = [];
      let userInvCount = 0;
      let deletedUserInvCount = 0;
      let userInvAmount = 0;
      let deletedUserInvAmount = 0;
      let monthWiseInvCount = [];

      db.userInvoices
        .findAll({
          attributes: [
            'deleted_at',
            [sequelize.fn('COUNT', sequelize.col('id')), 'count'],
            [sequelize.fn('SUM', sequelize.col('invoice_amount')), 'amount'],
            [sequelize.fn('MONTH', sequelize.col('invoice_date')), 'month']
          ],
          group: ['invoice_date', 'deleted_at'],
          paranoid: false
        })
        .then(result => {
          result.forEach(function(element) {
            userInvCount += element.dataValues.count;
            userInvAmount += element.dataValues.amount;
            if (element.dataValues.deleted_at != null) {
              deletedUserInvAmount += element.dataValues.amount;
              deletedUserInvCount += element.dataValues.count;
            }
            monthWiseInvCount.push(element.dataValues);
          });
          if (monthWiseInvCount.map(a => a === 'deleted_at')) {
            monthWiseInvCount.map(a => delete a.deleted_at);
          }
          promiseInvoices.push(
            userInvCount,
            userInvAmount,
            deletedUserInvCount,
            deletedUserInvAmount,
            monthWiseInvCount
          );
        });
      return promiseInvoices;
    }

在代码的主要部分我想调用这个函数并使用.then来获取返回的数组

你能帮我解决一下如何在函数中返回一个promise以及如何在.then部分中访问数组?

4 个答案:

答案 0 :(得分:1)

以下是您需要做的更改以获得预期结果:

function getInvoicesCount() {
    ...
    return  db.userInvoices.findAll({ //<-------- 1. First add return here
        ...
    }).then(result => {
        ...
        return promiseInvoices; //<----------- 2. Put this line inside the then
    });
    // return promiseInvoices; //<----------- Remove this line from here    
}

getInvoicesCount().then(data => {
    console.log(data); // <------- Check the output here
})
  

对此的说明:

     

要在功能正常时获取.then,函数应返回promise,   但在你的情况下,你只是返回一个空白数组,

     

根据sequlize doc,db.userInvoices.findAll返回   保证所以你需要做的就是在这个函数之前添加return   ,第一步已经完成

     

你在错误的地方return promiseInvoices;,为什么? ,因为   你永远不会得到结果,因为它上面的代码在异步中运行   方式,因为它是承诺,所以你将永远得到balnk阵列,到   得到你应该从中返回的预期结果   db.userInvoices.findAll的{​​{1}}函数如上面的代码

所示

答案 1 :(得分:0)

您应该从那时返回结果以在链中访问它。

function getInvoicesCount() {
  const promiseInvoices = []
  let userInvCount = 0
  let deletedUserInvCount = 0
  let userInvAmount = 0
  let deletedUserInvAmount = 0
  const monthWiseInvCount = []

  return db.userInvoices
    .findAll({
      attributes: [
        'deleted_at',
        [sequelize.fn('COUNT', sequelize.col('id')), 'count'],
        [sequelize.fn('SUM', sequelize.col('invoice_amount')), 'amount'],
        [sequelize.fn('MONTH', sequelize.col('invoice_date')), 'month'],
      ],
      group: ['invoice_date', 'deleted_at'],
      paranoid: false,
    })
    .then((result) => {
      result.forEach((element) => {
        userInvCount += element.dataValues.count
        userInvAmount += element.dataValues.amount
        if (element.dataValues.deleted_at != null) {
          deletedUserInvAmount += element.dataValues.amount
          deletedUserInvCount += element.dataValues.count
        }
        monthWiseInvCount.push(element.dataValues)
      })
      if (monthWiseInvCount.map(a => a === 'deleted_at')) {
        monthWiseInvCount.map(a => delete a.deleted_at)
      }
      return promiseInvoices.push(
        userInvCount,
        userInvAmount,
        deletedUserInvCount,
        deletedUserInvAmount,
        monthWiseInvCount,
      )
    })
}

您现在可以使用

getInvoicesCount().then(() => {
  //do something here
})

答案 2 :(得分:0)

getData(htmlData,tags)
.then(function(data) { 
     console.log(data); //use data after async call finished
})
.catch(function(e) {
    console.log(e);
});

function getData() {
  return new Promise(function(resolve, reject) {
    //call async task and pass the response
    resolve(resp); 
  });
}

答案 3 :(得分:0)

一般来说,你可以回复这样的承诺:

function returnPromise() {
    return new Promise((resolve, reject) => {
        resolve({foo: 'bar'});
    });
}

因此,虽然另一个答案完全正确,但您可以使用上述结构创建一个返回承诺的函数:

function getInvoicesCount() {
  return new Promise((resolve, reject) => {
    let promiseInvoices = [];
    let userInvCount = 0;
    let deletedUserInvCount = 0;
    let userInvAmount = 0;
    let deletedUserInvAmount = 0;
    let monthWiseInvCount = [];

  db.userInvoices
    .findAll({
      attributes: [
        'deleted_at',
        [sequelize.fn('COUNT', sequelize.col('id')), 'count'],
        [sequelize.fn('SUM', sequelize.col('invoice_amount')), 'amount'],
        [sequelize.fn('MONTH', sequelize.col('invoice_date')), 'month']
      ],
      group: ['invoice_date', 'deleted_at'],
      paranoid: false
    })
    .then(result => {
      result.forEach(function(element) {
        userInvCount += element.dataValues.count;
        userInvAmount += element.dataValues.amount;
        if (element.dataValues.deleted_at != null) {
          deletedUserInvAmount += element.dataValues.amount;
          deletedUserInvCount += element.dataValues.count;
        }
        monthWiseInvCount.push(element.dataValues);
      });
      if (monthWiseInvCount.map(a => a === 'deleted_at')) {
        monthWiseInvCount.map(a => delete a.deleted_at);
      }
      promiseInvoices.push(
        userInvCount,
        userInvAmount,
        deletedUserInvCount,
        deletedUserInvAmount,
        monthWiseInvCount
      );
      resolve(promiseInvoices); // When you are done, you resolve
    })
    .catch(err => reject(err)); // If you hit an error - reject
});
}

然而,这是一个相当大的功能,建议将其分成较小的部分。