如何在 sqlite3 db.get 和 db.all 中使用 async/await?

rv7*_*rv7 2 javascript sqlite node.js express async-await

这是我的服务器 mcve:

const express = require("express");
const app = express();
const fs = require("fs");

const dbFile = "./sqlite.db";
const exists = fs.existsSync(dbFile);
const sqlite3 = require("sqlite3").verbose();
const db = new sqlite3.Database(dbFile);

app.get("/", async (req, resp) => {
  await db.run(`INSERT INTO Times VALUES (${ Date.now() })`);
  let rows = await db.all("SELECT time FROM Times");
  console.log(rows); // The line where I console log rows
  resp.send(rows);
});

app.listen(process.env.PORT || 8080);
process.on("uncaughtException", console.log);
Run Code Online (Sandbox Code Playgroud)

上面的服务器正在记录一个数据库对象,如下所示,

Database {}
Run Code Online (Sandbox Code Playgroud)

每次刷新站点时都在控制台中,但我希望它记录我插入到数据库中的行。

我在这里做错了什么?

Rik*_*kus 17

NPM 上有几个 SQLite 包。

sqlite3

这是您正在使用的包。它是基于回调的,应该像这样使用:

db.all("SELECT time FROM Times", function(err, rows) { });
Run Code Online (Sandbox Code Playgroud)

注意:.all()函数返回数据库实例,而不是结果,因此您可以执行以下操作:db.all(query1, (err, rows) => {}).all(query2, (err, rows) => {});。Query2 不会等待 query1 完成。

sqlite

这是包的包装器sqlite3,实际上需要安装它才能运行。它基于承诺:

const rows = await db.all("SELECT time FROM Times");
Run Code Online (Sandbox Code Playgroud)

更好的sqlite

这是一个完全不同的包。它不像上面的两个示例那样异步运行查询,而是在主线程中运行每个查询。它的作者认为这更好(对于典型的 SQLite 工作负载)。

const rows = db.prepare("SELECT time FROM Times").all();
Run Code Online (Sandbox Code Playgroud)

  • 我已经在 NPM 上添加了软件包的链接。从那里,您可以点击进入相应的 Github 页面。他们的自述文件包含文档和链接,您可以在其中找到更多参考信息/帮助。 (2认同)

gij*_*joe 5

如果 sqlite3 不支持 async/await 那么你需要创建一个 async 函数,像这样的承诺

async function db_all(query){
    return new Promise(function(resolve,reject){
        db.all(query, function(err,rows){
           if(err){return reject(err);}
           resolve(rows);
         });
    });
}
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它

await db_all("SELECT time FROM Times");
Run Code Online (Sandbox Code Playgroud)

对需要使用的 sqlite3 中的每个函数使用相同的方法。

最好的方法是创建一个模块并覆盖您需要的所有这些方法