GOOGLE ADS

понедельник, 9 мая 2022 г.

Один ipcMain.on() работает в том же файле, а другой не работает?

Я разрабатываю приложение, используя Electron и vue.

Я использую это решение для связи между main и renderer, поэтому у меня есть три файла preload.js: main и renderer.

// preload.js
const { contextBridge, ipcRenderer } = require("electron");
contextBridge.exposeInMainWorld("api", {
send: (channel, data) => {
// whitelist channels
let validChannels = ["msgbox", "loadall", "savekv", "saveall"];
if (validChannels.includes(channel)) {
ipcRenderer.send(channel, data);
}
}
});
// main
const { ipcMain, dialog } = require('electron')
ipcMain.on("msgbox", (event, args) => dialog.showMessageBox({ message: args }))
ipcMain.on("saveall", (event, config) => dialog.showMessageBox({ message: config }))
// renderer
test() {
window.api.send("saveall", "hahaha"); // <- does not work
window.api.send("msgbox", "haha"); // <- work
}

Однако в файле рендеринга window.api.send("msgbox", "haha");работает, а window.api.send("saveall", "hahaha");нет.

Версия Electron 13.6.6 macOS Monterey 12.1


Решение проблемы

Теоретически нет причин, по которым оба диалоговых окна не должны отображаться одновременно ( hahahaтогда haha).

На самом деле я заметил, что в 50% случаев только одно из двух диалоговых окон будет отображаться при первоначальном нажатии на файл button. Выбор диалогового окна был случайным, когда отображалось только одно. Я подозреваю, что это может иметь какое-то отношение к внутренней работе Javascript стека и цикла событий.

Чтобы оба диалоговых окна отображались все время, задержка отображения второго диалогового окна всего на 10 мс будет работать в 100% случаев. Кроме того, порядок диалоговых окон всегда будет гарантирован. ИИ: hahahaтогда haha.

Приведенные выше результаты были протестированы как на Electron v13.6.6, так и на Electron v18.1.0 (Windows 10) с приведенным ниже кодом.

preload.js(основной процесс)

const contextBridge = require('electron').contextBridge;
const ipcRenderer = require('electron').ipcRenderer;
contextBridge.exposeInMainWorld(
'api', {
send: (channel, args) => {
let validChannels = ["msgbox", "loadall", "savekv", "saveall"];
if (validChannels.includes(channel)) {
ipcRenderer.send(channel, args);
}
}
}
);

main.js(основной процесс)

const electronApp = require('electron').app;
const electronBrowserWindow = require('electron').BrowserWindow;
const electronDialog = require('electron').dialog;
const electronIpcMain = require('electron').ipcMain;
const nodePath = require('path');
let window;
function createWindow() {
const window = new electronBrowserWindow({
x: 0,
y: 0,
width: 800,
height: 600,
show: false,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
preload: nodePath.join(__dirname, 'preload.js')
}
});
window.loadFile('index.html')
.then(() => { window.show(); });
return window;
}
electronApp.on('ready', () => {
window = createWindow();
});
electronApp.on('window-all-closed', () => {
if (process.platform!== 'darwin') {
electronApp.quit();
}
});
electronApp.on('activate', () => {
if (electronBrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
// ---
electronIpcMain.on('msgbox', (event, args) => {
console.log(args); // Testing
electronDialog.showMessageBox({message: args} )
});
electronIpcMain.on('saveall', (event, config) => {
console.log(config); // Testing
electronDialog.showMessageBox({message: config} )
});

index.html(процесс рендеринга)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Electron Test</title>
</head>
<body>
<input type="button" id="button" value="button">
</body>
<script>
document.getElementeById('button').addEventListener('click', () => {
// Test 1 - Inconsistent results
window.api.send("saveall", "hahaha");
window.api.send("msgbox", "haha");
// Test 2 - Consistent results
// window.api.send("saveall", "hahaha");
// setTimeout(() => { window.api.send("msgbox", "haha"); }, 10);
});
</script>
</html>

Комментариев нет:

Отправить комментарий

Laravel Datatable addColumn returns ID of one record only

Я пытаюсь использовать Yajra Datatable для интеграции DataTable на свой веб-сайт. Я смог отобразить таблицу, но столкнулся с проблемой. В по...