Reputation: 742
Can I run something after every row has been processed by db.each?
var email = openEmailConnection();
db.each("SELECT * FROM mytable", async (err, row) => {
var x = await makeNetworkApiCall();
await email.sendMail({message: "your message: " + x});
console.log("finished");
});
//somehow call closeEmailConnection() after all async callbacks have finished
I don't want to do db.all because that loads everything onto memory. Maybe I could do something with promises and Promise.all?
Upvotes: 1
Views: 1177
Reputation: 86
Maybe you could use an anonymous callback function. I used a similar construction to add rows to an array and returning that array after all callbacks of the rows are completed:
select = (db, tableName) => {
const rows = [];
return new Promise((resolve, reject) => {
const sql = `SELECT * FROM ${tableName}`
db.each(sql, (err, row) => {
if (err) {
console.error(err.message);
}
rows.push(row);
}, () => {
resolve(rows);
});
})
}
For your code this would be something like this:
const email = openEmailConnection();
db.each("SELECT * FROM mytable", async (err, row) => {
var x = await makeNetworkApiCall();
await email.sendMail({message: "your message: " + x});
console.log("finished");
}, () => {
closeEmailConnection();
});
Upvotes: 1
Reputation: 74046
Maybe as an alternative, I suggest to use better-sqlite3
instead. Here, you have an iterate()
function that allows you to process all entries in a for loop like this (from their docu, slightly adapted):
const email = openEmailConnection();
const stmt = db.prepare('SELECT * FROM mytable');
for (const entry of stmt.iterate()) {
const x = await makeNetworkApiCall();
await email.sendMail({message: "your message: " + x});
}
closeEmailConnection();
Upvotes: 1