Электрон: Выполнить sqlite (лучше-sqlite) операции с БД в другом потоке

Я разрабатываю настольное приложение, используя платформу Electron, и мне нужно использовать базу данных sqlite для данных приложения. Я решил использовать better-sqlite3 потому что:

  1. Поддержка пользовательских функций SQL (для меня это очень важно)
  2. Это намного быстрее чем node-sqlite3 в большинстве случаев
  3. Это просто в использовании.
  4. Это синхронный API (в большинстве случаев мне нужно сериализовать данные)

но в некоторых случаях, когда я выполняю запрос, для ответа которого требуется некоторое время, пользовательский интерфейс приложения не отвечает пользователю, пока запрос не завершится.

Как я могу выполнить несколько запросов БД в другом потоке? или запустить их асинхронно (как node-sqlite3)?

Извините за плохой английский

1 ответ

Узел позволяет вам отдельный процесс " из коробки". (Потоки - это другое дело - увы, нет WebWorkers:(хотя вы можете найти дополнение к потоку lib где-нибудь.

У меня была та же проблема, что и у вас - мне нужен синхронный код для запуска без блокировки основного потока, и я использовал дочерний процесс. Это было для лучшего sqlite тоже!

Проблема в том, что обработка io-потоков, sigints и т. Д. Для контроля не сразу очевидна и зависит от того, работаете ли вы на windows или posix.

Я использую разветвленный дочерний процесс с параметром silent, установленным в true, для синхронной работы с БД

Если вам нужен контроль над этим процессом или отчеты об обновлении прогресса обратно в основной процесс для графического интерфейса пользователя во время синхронизации; Я контролирую / связываюсь с дочерним процессом, читая / записывая в stdin/out дочернего процесса с использованием fileSystem writeFileSync / readFileSync в различных точках моего дочернего процесса (вы не можете использовать обычные api межпроцессных comms во время операций синхронизации, так как это управляемый событиями и не может работать во время выполнения синхронного кода. Хотя вы можете смешивать и сочетать два типа 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();
Другие вопросы по тегам