sqlite3-异步调用的承诺 [英] sqlite3 - promise for asynchronous calls
问题描述
我想选择一个sqlite3数据库的异步数据.但是由于 db.each
是一个异步函数,所以我下面的 select
函数无法正常工作.如何添加一个Promise以等待结果?
I want to select asynchronous some data of a sqlite3 database. But since db.each
is a asynchron function my following select
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));
});
}
推荐答案
db.each()
由于其回调的性质而需要稍微麻烦的,非标准的promisification,通过该回调,它可以:
db.each()
requires a slightly cumbersome, non-standard promisification due to the nature of its callbacks, through which it :
- 一次传送一行到第一个回调,
- 信号完成到第二个回调.
将其与 db.all()
中显示的标准模式进行比较,该模式将使用签名为(err,rows)
的单个回调.
Compare that with the standard pattern exhibited in db.all()
, which takes a single callback with the signature (err, rows)
.
与 db.each()
匹配,您所写的内容就目前而言是正确的,但在完成 db.each()
后仍无法解决Promise>.
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()
.
幸运的是,尽管很麻烦,但解决方案还是很简单的.可以从第二个回调中调用 resolve(queries)
.
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
}
});
});
}
如果预期的行数非常有限"(如SQLite文档中所述),请改用 db.all()
.
If the expected number of rows is "very limited" (as it says in the SQLite documentation), then use db.all()
instead.
这篇关于sqlite3-异步调用的承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!