0

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

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

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

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

抱歉英语不好

4

1 回答 1

1

Node 允许您开箱即用的单独进程。(线程是另一回事 - 唉,没有 WebWorkers :( 虽然你可以在某个地方找到一个线程插件库。

编辑:自从我最初发布这个答案以来,节点已经添加了 worker_threads。还没有尝试过/不知道他们是否与更好的sqlite一起工作。结束编辑

我和你有同样的问题——需要同步代码在不阻塞主线程的情况下运行,我使用了一个子进程。这也是为了更好的sqlite!

问题是如何处理 io 流和信号等以进行控制并不是很明显,并且取决于您是在 Windows 上运行还是在 posix 上运行而有所不同。

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

如果您需要在同步操作期间控制该过程或进度更新报告回您的 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();
于 2018-02-01T08:28:28.443 回答