最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - sqlite3 - promise for asynchronous calls - Stack Overflow

programmeradmin4浏览0评论

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

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

Share Improve this question asked Oct 28, 2017 at 20:32 tomoletomole 1,0063 gold badges15 silver badges37 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 19

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.

发布评论

评论列表(0)

  1. 暂无评论