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

时间:2018-01-31 08:01:05

标签: node.js multithreading sqlite electron better-sqlite3

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

  1. 自定义SQL函数支持(这对我来说非常重要)
  2. 在大多数情况下,它比node-sqlite3快得多
  3. 使用简单。
  4. 它是同步API(在大多数情况下,我需要将数据序列化)
  5. 但在某些情况下,当我执行需要一段时间才能响应的查询时,在查询结束之前,应用程序UI不会响应用户。

    如何在另一个线程中运行一些数据库查询?或者运行它们asyncronized(如node-sqlite3)?

    抱歉英语不好

1 个答案:

答案 0 :(得分:0)

Node允许您单独的进程开箱即用。 (线程是另一回事 - 唉没有WebWorkers :(虽然你可以找到一个线程附加的lib somwhere。

我遇到了和你一样的问题 - 需要同步代码才能运行而不会阻塞主线程并且我使用了子进程。这也是为了更好的sqlite!

问题是如何处理io流和sigints等以进行控制并不是很明显,并且取决于你是在windows还是posix上运行。

我使用一个forked子进程,其中silent选项设置为true来执行同步db工作。

如果您需要在同步操作期间控制该过程或进度更新报告回到您的gui主流程;我通过在子进程代码中的各个点使用fileSystem writeFileSync / readFileSync读取/写入子进程stdin / out来控制/通信子进程(在同步操作期间不能使用正常的进程间通信api,因为这是事件驱动,并且在同步代码运行时无法运行。虽然你可以混合和匹配两种类型的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();