sqlite3-异步调用的承诺

tom*_*ole 2 javascript sqlite asynchronous promise

我想选择一个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));
  });
}
Run Code Online (Sandbox Code Playgroud)

代码片段的结果

Roa*_*888 6

db.each() 由于其回调的性质,因此需要稍微繁琐的,非标准的promisification,通过它可以:

  • 一次传送一行到第一个回调,
  • 向第二个回调发出信号。

将其与其中显示的标准模式进行比较,该模式db.all()需要一个带有签名的回调(err, rows)

坚持db.each()下去,你所写的东西到目前为止都是正确的,但是在完成时仍不能解决Promise 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
            }
        });
    });
}
Run Code Online (Sandbox Code Playgroud)

如果预期的行数“非常有限”(如SQLite文档中所述),请db.all()改用。

  • 这不是最终必须像 `all()` 那样将整个结果集加载到内存中吗?我没有更好的解决方案,我只是一个相对的 JS n00b,我正试图弄清楚如何通过大结果集来提高内存效率。 (2认同)