sqlite3 - promise for asynchronous calls
db.each()
requires a slightly cumbersome, non-standard promisification due to the nature of its callbacks, through which it :
- delivers rows, one at a time, to a first callback,
- signals completion to a second callback.
Compare that with the standard pattern exhibited in db.all()
, which takes a single callback with the signature (err, rows)
.
Sticking with db.each()
, what you have written is correct as far as it goes but stops short of resolving the Promise on completion of db.each()
.
Fortunately the solution, despite being cumbersome, is fairly simple. resolve(queries)
can be called from a second, callback.
export default function select(database, table) {
return new Promise((resolve, reject) => {
const db = new sqlite3.Database(database);
const queries = [];
db.each(`SELECT rowid as key, * FROM ${table}`, (err, row) => {
if (err) {
reject(err); // optional: you might choose to swallow errors.
} else {
queries.push(row); // accumulate the data
}
}, (err, n) => {
if (err) {
reject(err); // optional: again, you might choose to swallow this error.
} else {
resolve(queries); // resolve the promise
}
});
});
}
If the expected number of rows is "very limited" (as it says in the SQLite documentation), then use db.all()
instead.
tomole
Updated on July 03, 2022Comments
-
tomole almost 2 years
I want to select asynchronous some data of a sqlite3 database. But since
db.each
is a asynchron function my followingselect
function doesn't work properly. How to add a Promise to wait for the result?const sqlite3 = require('sqlite3').verbose(); export default function select(database, table) { return new Promise((resolve, reject) => { const db = new sqlite3.Database(database); const queries = []; db.each(`SELECT rowid as key, * FROM ${table}`, (err, row) => { if (err) { reject(err); } console.log(`Push row ${row.key} from database.`); queries.push(row); }); console.log(queries); console.log(JSON.stringify(queries)); }); }