Electron:在另一个线程中执行 sqlite (better-sqlite) db 操作

Electron: Perform sqlite (better-sqlite) db operations in another thread

我正在使用 Electron 框架开发桌面应用程序,我必须使用 sqlite 数据库来存储应用程序数据。 我决定使用 better-sqlite3 因为:

  1. 自定义SQL功能支持(对我来说很重要)
  2. 大多数情况下比node-sqlite3快很多
  3. 使用简单
  4. 它是同步的API(大多数情况下我需要序列化数据)

但在某些情况下,当我执行需要一段时间才能响应的查询时,应用程序 UI 在查询结束之前不会响应用户。

如何 运行 在另一个线程中进行一些数据库查询?或者 运行 它们被异步化了(比如 node-sqlite3)?

抱歉英语不好

Node 允许您开箱即用的单独 进程。 (线程是另一回事 - 唉,没有 WebWorkers :( 尽管你可能会在某处找到一个线程附加库。

编辑:自从我最初发布此答案后,节点已添加 worker_threads。还没有尝试过/不知道他们是否与 better-sqlite 一起工作。结束编辑

我遇到了和你一样的问题 - 需要同步代码 运行 而不阻塞主线程,我使用了一个子进程。这也是为了 better-sqlite!

问题是如何处理 io 流和 signints 等以进行控制并不是立即显而易见的,并且根据您 运行 是 windows 还是 posix 而有所不同。

我使用静默选项设置为 true 的分叉子进程来执行同步数据库工作。

如果您需要控制该进程或在同步操作期间将进度更新报告回您的主进程以供您的图形用户界面使用;我 control/communicate 通过 reading/writing 对子进程 stdin/out 使用文件系统 writeFileSync / readFileSync 在我的子进程代码的不同点上使用子进程(你不能使用正常的进程间通信api 在同步操作期间,因为它是事件驱动的,并且在同步代码 运行ning 时无法操作。尽管您可以混合和匹配两种类型的 io)

分叉子进程示例;

//parent.js and child.js in same folder

//parent.js
process.on('exit', (code) => {
  console.log(`Parent to exit with code: ${code}`);
});

const readLine = require("readline") ;
const cp = require('child_process');

var forkOptions = {
    //execArgv:['--inspect-brk'], // uncomment if debugging the child process
    silent:true // child gets own std pipes (important) whch are piped to parent
};
var childOptions = [] ;
const child = cp.fork(`./child.js`,childOptions,forkOptions);


//for messages sent from child via writeSync
const childChannel = readLine.createInterface({
    input: child.stdout
}).on("line",function(input){
    console.log("writeSync message received from child: " + input) ;
});

//for messages sent from child via process.send
child.on('message', (m) => { 
    console.log("process.send message received from child: " + m) ;
});


// Child.js
process.on('exit', (code) => {
  console.log(`Child to exit with code: ${code}`);
});

const fs = require('fs');

function doSyncStuff(){    
    for(let i = 0 ; i < 20 ; i++){
        //eg. sync db calls happening here
        process.send(`Hello via process.send from child. i = ${i} \n`); // async commms . picked up by parent's "child.on" event
        fs.writeFileSync(process.stdout.fd,`Hello via writeFileSync from child. i = ${i} \n`) ; // sync comms. picked up by parent's readLine listener ("process" here is the child )           
    }
}

doSyncStuff();