Почему мой ipcMain возвращает пустой массив после чтения базы данных?

В моем проекте я использую электрон и взаимодействую с 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, которое выведет массив на консоль.

db.each — это асинхронная операция... Вы должны переместить event.sender.send(channels.GET_LOGIN, cateNames); внутрь обратного вызова.
Eldar 22.03.2022 15:49

@AK Какую БД вы используете?

midnight-coding 22.03.2022 22:46

@midnight-кодирование Sqlite3.

A. K 23.03.2022 16:41
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
3
26
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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);
    });
});

Другие вопросы по теме