Я хочу выбрать асинхронные данные базы данных sqlite3. Но поскольку db.each
является асинхронной функцией, моя следующая функция select
работает неправильно. Как добавить обещание подождать результата?
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));
});
}
db.each()
требует немного громоздкого, нестандартного обещания из-за характера его обратных вызовов, через которые он:
Сравните это со стандартным шаблоном, выставленным в db.all()
, который принимает один обратный вызов с сигнатурой (err, rows)
.
Придерживаясь db.each()
, то, что вы написали, правильно, насколько это возможно, но не позволяет решить обещание по завершении db.each()
.
К счастью, решение, несмотря на громоздкость, довольно просто. resolve(queries)
можно вызвать из второго обратного вызова.
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
}
});
});
}
Если ожидаемое количество строк "очень ограничено" (как сказано в документации SQLite), используйте вместо этого db.all()
.
all()
? У меня нет лучшего решения, я просто относительный JS n00b, и я пытаюсь понять, как эффективно использовать память с большими наборами результатов.