sqlite3 - 承诺异步调用

时间:2017-10-28 20:32:07

标签: javascript asynchronous sqlite promise

我想选择异步sqlite3数据库的一些数据。但由于db.each是一个异步函数,我的后续select函数无法正常工作。 如何添加Promise以等待结果?

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));
  });
}

result of codesnippet

1 个答案:

答案 0 :(得分:2)

由于其回调的性质,

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()代替。