В моем проекте я использую электрон и взаимодействую с ipcRenderer и ipcMain для связи с базой данных. Я вижу, что он проходит через базу данных, но возвращает пустой массив. Это похоже на то, что массив возвращается до того, как что-либо будет прочитано из БД.
Вот код, который я использую в своем ipc main: Я ожидаю, что он вернет имена категорий, но все это возвращает пустые cateNames.
ipcMain.on(channels.GET_CATS, async(event,type) => {
console.info("made it")
let cateNames=[];
db.each(`SELECT name FROM categories WHERE type=?`, [type],(err, row) => {
if (err) {
return console.error(err.message);
}
console.info(row.name);
cateNames.push(row.name);
});
console.info(cateNames);
event.sender.send(channels.GET_LOGIN, cateNames);
});
Я отправляю запрос с
ipcRenderer.send(channels.GET_CATS,"Donation");
с прослушиванием ipcRenderer.on, которое выведет массив на консоль.
@AK Какую БД вы используете?
@midnight-кодирование Sqlite3.
Javascript/Node.js выполняют команды в последовательном порядке и не «ждут» при переходе от одной команды к следующей пока не, явно указанному с помощью промисов и асинхронных/ожидающих команд.
Причина, по которой ваш текущий код возвращает пустой массив cateNames
, заключается в том, что выполнение кода не «ждет», пока команда db.each
вернет свой обратный вызов. Обратный вызов возвращается только после того, как БД будет что-то возвращать, что будет либо строкой, либо ошибкой. Это требует времени. Тем временем выполнение перешло к следующей команде.
Чтобы заставить этот блок кода «ждать», пока БД не вернет все доступные строки (если они есть), мы могли бы использовать обещания.
Вместо этого я предлагаю более простой метод. Вместо того, чтобы push
писать row.name
с каждой db.each
итерацией, просто используйте db.all
и потом создавайте ответ.
ipcMain.on(channels.GET_CATS, async(event, type) => {
console.info("made it")
let cateNames = [];
db.all(`SELECT name FROM categories WHERE type=?`, [type], (err, rows) => {
if (err) {
return console.error(err.message);
}
for (let row of rows) {
cateNames.push(row.name);
}
console.info(cateNames);
// Use event.reply(channel, data);
event.reply(channels.GET_LOGIN, cateNames);
});
});
db.each
— это асинхронная операция... Вы должны переместитьevent.sender.send(channels.GET_LOGIN, cateNames);
внутрь обратного вызова.