Я пытаюсь создать функцию в узле 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 для получения возвращенного массива
Не могли бы вы мне помочь, как я могу вернуть обещание в функции и как будет доступен массив в части .then?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вот что нужно сделать, чтобы получить ожидаемый результат:
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.info(data); // <------- Check the output here
})
Explanation for this :
To get
.thenwhen you can function , function should returnpromise, but in you case you are just returning a blank array ,As per the sequlize doc ,
db.userInvoices.findAllreturns the promise so all you need to do is addreturnbefore the this function , First step is doneYou were
return promiseInvoices;at wrong place , why ? , coz at that you will never get the result , as the code above it run in async manner as it is promise , so you will always get the balnk array , to get the expected result you should return it fromdb.userInvoices.findAll'sthenfunction as shown above in code
Вы должны вернуть результаты, чтобы получить к нему доступ в цепочке.
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
})
getData(htmlData,tags)
.then(function(data) {
console.info(data); //use data after async call finished
})
.catch(function(e) {
console.info(e);
});
function getData() {
return new Promise(function(resolve, reject) {
//call async task and pass the response
resolve(resp);
});
}
Обычно вы можете вернуть обещание следующим образом:
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
});
}
Однако это довольно большая функция, рекомендуется разделить ее на более мелкие части.
@JonathanLonowski, Готово, пожалуйста, посмотрите