首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ipcRenderer.on不是一个函数

ipcRenderer.on不是一个函数
EN

Stack Overflow用户
提问于 2021-04-02 01:58:38
回答 4查看 4.4K关注 0票数 7

我使用的是Main > Preload > Renderer进程堆栈。

preload.js

代码语言:javascript
复制
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('ipcRenderer', ipcRenderer)

renderer.js

代码语言:javascript
复制
console.log(ipcRenderer) // it shows something like:
/**
{_events: {…}, _eventsCount: 0, _maxListeners: undefined, send: ƒ, sendSync: ƒ, …}
invoke: ƒ ()
postMessage: ƒ ()
send: ƒ ()
sendSync: ƒ ()
sendTo: ƒ ()
sendToHost: ƒ ()
Symbol(kCapture): false
_events: {}
_eventsCount: 0
_maxListeners: undefined
__proto__: Object
**/

console.log(ipcRenderer.on) // undefined

当尝试使用ipcRenderer.on()方法时,它正在记录一个错误:

代码语言:javascript
复制
Uncaught TypeError: ipcRenderer.on is not a function

这个方法在新版本中被删除了吗?是什么导致它在渲染程序过程中不可用?

EN

回答 4

Stack Overflow用户

发布于 2021-11-22 13:28:23

这里有个小小的解决办法。但我不认为这是一个安全的好主意。

代码语言:javascript
复制
const { contextBridge, ipcRenderer } = require("electron");    
contextBridge.exposeInMainWorld("electron", { ipcRenderer: { ...ipcRenderer, on: ipcRenderer.on } });
票数 5
EN

Stack Overflow用户

发布于 2022-03-08 14:58:34

正如ipcRenderer的电子API文档所述,“ipcRenderer模块是一个EventEmitter”。

电子引用的这个" EventEmitter“是node.js的EventEmitter类。电子的ipcRenderer模块继承了节点的EventEmitter类。

console.log(ipcRenderer)可以看到的方法是电子的方法。所有继承的方法都在Prototype对象中找到,这正是您将在其中找到on()方法的地方。

要查看此操作,请将console.log(ipcRenderer)添加到典型的、格式良好、安全和可读的preload.js脚本中。

preload.js (主线程)

代码语言:javascript
复制
// Import the necessary Electron components.
const contextBridge = require('electron').contextBridge;
const ipcRenderer = require('electron').ipcRenderer;

// White-listed channels.
const ipc = {
    'render': {
        // From render to main.
        'send': [],
        // From main to render.
        'receive': [],
        // From render to main and back again.
        'sendReceive': []
    }
};

// Exposed protected methods in the render process.
contextBridge.exposeInMainWorld(
    // Allowed 'ipcRenderer' methods.
    'ipcRender', {
        // From render to main.
        send: (channel, args) => {
            let validChannels = ipc.render.send;
            if (validChannels.includes(channel)) {
                ipcRenderer.send(channel, args);
            }
        },
        // From main to render.
        receive: (channel, listener) => {
            let validChannels = ipc.render.receive;
            if (validChannels.includes(channel)) {

                // Show me the prototype (use DevTools in the render thread)
                console.log(ipcRenderer);

                // Deliberately strip event as it includes `sender`.
                ipcRenderer.on(channel, (event, ...args) => listener(...args));
            }
        },
        // From render to main and back again.
        invoke: (channel, args) => {
            let validChannels = ipc.render.sendReceive;
            if (validChannels.includes(channel)) {
                return ipcRenderer.invoke(channel, args);
            }
        }
    }
);

现在,打开Chrome的DevTools并查看Console选项卡。

Chrome DevTools - Console Tab Output (渲染线程)

代码语言:javascript
复制
v EventEmitter
  > invoke: async ƒ (e,...t)
  > postMessage: ƒ (e,t,n)
  > send: ƒ (e,...t)
  > sendSync: ƒ (e,...t)
  > sendTo: ƒ (e,t,...n)
  > sendToHost: ƒ (e,...t)
  > _events: {app:versions: ƒ}
    _eventsCount: 1
    _maxListeners: undefined
    Symbol(kCapture): false
  v [[Prototype]]: Object
    > addListener: ƒ addListener(type, listener)
    > emit: ƒ emit(type, ...args)
    > eventNames: ƒ eventNames()
    > getMaxListeners: ƒ getMaxListeners()
    > listenerCount: ƒ listenerCount(type)
    > listeners: ƒ listeners(type)
    > off: ƒ removeListener(type, listener)
    v on: ƒ addListener(type, listener)        // <-- Here it is
        length: 2
        name: "addListener"
      > prototype: {constructor: ƒ}
        arguments: (...)
        caller: (...)
        [[FunctionLocation]]: VM14 node:events:486
        [[Prototype]]: ƒ ()
        [[Scopes]]: Scopes[2]
    > once: ƒ once(type, listener)
    > prependListener: ƒ prependListener(type, listener)
    > prependOnceListener: ƒ prependOnceListener(type, listener)
    > rawListeners: ƒ rawListeners(type)
    > removeAllListeners: ƒ removeAllListeners(type)
    > removeListener: ƒ removeListener(type, listener)
    > setMaxListeners: ƒ setMaxListeners(n)
      _events: undefined
      _eventsCount: 0
      _maxListeners: undefined
    > constructor: ƒ EventEmitter(opts)
      Symbol(kCapture): false
    > [[Prototype]]: Object
票数 1
EN

Stack Overflow用户

发布于 2022-03-08 03:35:13

这里有个小小的解决办法。

代码语言:javascript
复制
// preload.ts
contextBridge.exposeInMainWorld('_Electron_Event_Listener_', {
    onCreateBrowserView,
})

function onCreateBrowserView(listener: (event: IpcRendererEvent, ...args: any[]) => void) {
    ipcRenderer.removeAllListeners('/browserView/create')
    ipcRenderer.on('/browserView/create', listener)
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66913598

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档