无法从主进程向 Electron Renderer 进程发送函数

Posted

技术标签:

【中文标题】无法从主进程向 Electron Renderer 进程发送函数【英文标题】:Cannot send function to Electron Renderer process from Main Process 【发布时间】:2020-02-20 08:28:02 【问题描述】:

我想将一个函数从我的主进程发送到渲染器进程

我有一个从 db.services.js 模块导出的函数

// db.services.js
const MongoClient = require('mongodb').MongoClient;
const assert = require('assert')

var DatabaseService = (function () 
    "use strict";
    var instance; //prevent modification of "instance" variable
    function Singleton() 
        if (instance) 
            return instance;
        
        instance = this;
    

    Singleton.create = function (db_uri) 
        //Singleton initialization code
        this.db_uri = db_uri
        this.db = undefined
        this.a = 0 // debugging async behavior
    

    //instance accessor
    Singleton.getInstance = function () 
        return instance || new Singleton();
    ;

    Singleton.getDB = function () 
        return this.db.db('xFilterDB') // directly return the used DB
    

    Singleton.establishConnection = function (callback) 
        ... 
    

    return Singleton;
());

// exporting a "singleton" object to use with all views
DatabaseService.getInstance();

module.exports = DatabaseService;

我将函数“导入”到我的主电子进程app.js

// app.js

const 
    app,
    BrowserWindow,
    ipcMain
 = require('electron');

const isDev = require('electron-is-dev');
const DatabaseService = require('./services/db.services'); 
app.on('ready', function () 
    DatabaseService.getInstance();
    DatabaseService.create("mongodb://localhost:27017");

    mainWindow = new BrowserWindow(
        width: 1024,
        height: 768,
        webPreferences: 
            nodeIntegration: true
        
    )
    let url = 'file://' + __dirname + '/views/main.html'
    mainWindow.loadURL(url)
    mainWindow.webContents.on('did-finish-load', () => 
        console.log(DatabaseService);

        // 
        // [Function: Singleton] 
        //   create: [Function],
        //   getInstance: [Function],
        //   getDB: [Function],
        //   establishConnection: [Function],
        //   db_uri: 'mongodb://localhost:27017',
        //   db: undefined,
        //   a: 0
        // 

        mainWindow.webContents.send('database-service', 
            DatabaseService);  // <-- I am sending the function here
    );
    windows.push(mainWindow)

在 main.html 我做

<script>
        require('./main.js')
</script>

在 main.js 中

//main.js

ipcRenderer.on('database-service', (event, args) => 
    // ----- mongo connection ESTABLISH REGION START----
    // implicit async
    console.log(args); // <-- args is null here 
    ...

知道这里出了什么问题吗?

另外,显然这个webContents.send('database-service', DatabaseService) 已被弃用。所以更好的解决方案将受到双重赞赏。

【问题讨论】:

请解释对该问题的反对意见。 【参考方案1】:

你不能通过IPC通道发送函数,因为它不能被序列化。

来自docs:

通过通道向渲染器进程发送异步消息, 连同论点。参数将使用结构化序列化 克隆算法,就像 postMessage,所以原型链不会 被包括在内。发送函数、承诺、符号、WeakMaps 或 WeakSets 会抛出异常。

【讨论】:

是的,显然我需要使用 ipcMain.handle()ipcRenderer.invoke()

以上是关于无法从主进程向 Electron Renderer 进程发送函数的主要内容,如果未能解决你的问题,请参考以下文章

Electron - 限制从主进程到渲染进程的消息流

electron 中renderer.js中使用require('electron') 报错require is not defined

使用electron中遇到的问题总结

你第一个Electron应用 | Electron in Action(中译)

Electron 渲染进程主进程通信 02

Electron 渲染进程主进程通信 01