Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nodejs array of promises, how can I do this?

I am very new to async programming and have never done a queue of promises before, so I have no idea how to solve this.

I have a table with bank-accounts

for each bank account I have a list of receipts

Account 111
 - Receipt 001
 - Receipt 002
 - Receipt 003

Account 222
 - Receipt 004
 - Receipt 005
 - Receipt 006

So I set up a promise that find() all the bank accounts.

And then I loop thru all bank accounts, and for each account I find all receipts.

What should I do? Create a promise for each receipt find()?

Create an array of promises? (how do you do that btw)

Or is there a third option?

// 
// Find all bank accounts
// 
var findBank = new Promise(
    (resolve, reject) => {
    bankTable.find({}
    ,function(err, data) {
        if (!err) {
            resolve(data);
        } else {
            reject(new Error('findBank ERROR : ' + err));
        }
    });
});


// 
// Find the RECEIPTS for each bank account
// 
var findAllReceipts = function(accountArray) {

    for (var i=0; i<accountArray.length; i++) {

        var findReceipt = new Promise(
            (resolve, reject) => {
            receiptTable.find(
                { accountNo: accountArray[i].accountNo } 
            ,function(err, data) {
                if (!err) {
                    resolve(data);
                } else {
                    reject(new Error('findPrice ERROR : ' + err));
                }
            });
        });
    }
}

// 
// Run the promises
// 
findBank
    .then(findAllReceipts)
    .catch(err => {
        console.log("getbankAccountReport ERR: " + err);
        res.json({error:true,err})
    })
like image 718
torbenrudgaard Avatar asked May 18 '17 07:05

torbenrudgaard


1 Answers

Here is how you can do it:

let findAllReceipts = function (accountArray) {
    const a = [];

    for (let i = 0; i < accountArray.length; i++) {
        a.push(new Promise((resolve, reject) => {
            receiptTable.find({accountNo: accountArray[i].accountNo}, function (err, data) {
                if (!err) {
                    resolve(data);
                } else {
                    reject(new Error('findPrice ERROR : ' + err));
                }
            });
        }));
    }

    return Promise.all(a);
};

Or this way using all capabilities of the language:

let findAllReceipts = function (accountArray) {
    return Promise.all(accountArray.map(findReceipts));
};

function findReceipts(account) {
    return new Promise((resolve, reject) => {
        receiptTable.find({accountNo: account.accountNo}, function (err, data) {
            if (!err) {
                resolve(data);
            } else {
                reject(new Error('findPrice ERROR : ' + err));
            }
        });
    });
}
like image 67
Max Koretskyi Avatar answered Oct 13 '22 02:10

Max Koretskyi