繁体   English   中英

节点.on方法触发次数太多

[英]Node .on method firing too many times

我有一个Electron应用程序,向用户显示目录列表。 当用户单击按钮时,我的界面脚本interface.js清除容器div并向main.js发送消息。 收到消息后,main.js将目录扫描成文件名数组,并将数组作为响应返回给interface.js。 Interface.js使用.on方法,该方法在收到响应时触发,并使用数组内容更新容器div。

这是我第一次使用Node的真正尝试,就接口行为而言,一切都运行得非常出色! 很棒,它只有几个小时,我已经爱上了Node!

但是,在调试/压力测试时,我将.on方法中返回的数组打印到控制台,并注意到一些奇怪的行为。 用户第一次单击该按钮时,.on方法将运行一次(通过一条消息验证到控制台)。 用户第二次单击时,该方法运行两次(通过两条消息验证到控制台); 它第三次运行三次,依此类推。

main.js中扫描目录的函数每次点击只运行一次,因此问题必须在inteface.js内。

我的main.js和interface.js的代码:

main.js:

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

...

ipcMain.on( 'list-directory', ( event, directory ) => {
    var files = fs.readdirSync( directory );
    event.sender.send( 'list-directory-reply', files );
});

interface.js

var { ipcRenderer, remote } = require( 'electron' );  
var main = remote.require( "./main.js" );

...

button.addEventListener('click', function(){ showDialogue( this ); }, false );

...

showDialogue( select ) {
    // clear the dialogue
    // some other stuff
    ipcRenderer.send( 'list-directory', './files/documents/' );
    ipcRenderer.on( 'list-directory-reply', function( event, contents ) {
        console.log( contents );
        if ( contents.length > 0 ) {
            // add contents to the dialogue
        }
    } );
}

该代码改编自Electron网站上的教程。

为什么ipcRenderer.on会多次运行? 每次点击按钮时它是否可能被绑定,因此可以像过去的点击一样运行多次? 我在事件监听器函数中放置了一个print语句,并在ipcRenderer之前的showDialogue函数内部,但是它们每次只打印一次,所以重复肯定只来自ipcRenderer.on

正如@planet_hunter所提到的,每次调用showDialogue()都会设置一个监听器。 您需要删除侦听器或将侦听器移出调用函数。

但是,我发现更清晰的解决方案是使用.once命令。 这类似.on ,但不是手动删除.on监听器(你还没有),它会自行删除。

showDialogue( select ) {
    // clear the dialogue
    // some other stuff
    ipcRenderer.send( 'list-directory', './files/documents/' );
    ipcRenderer.once( 'list-directory-reply', function( event, contents ) {
        console.log( contents );
        if ( contents.length > 0 ) {
            // add contents to the dialogue
        }
    } );
}

您在每次单击按钮后订阅ipcRenderer.on ,这会导致多个订阅。 尝试在ipcRenderer.on事件之外定义ipcRenderer.on事件处理程序,它应该可以正常工作。

像这样的东西 -

button.addEventListener('click', function(){ showDialogue( this ); }, false );


ipcRenderer.on( 'list-directory-reply', function( event, contents ) {
    // ipcRenderer event handler
});

showDialogue(select) {
    ipcRenderer.send( 'list-directory', './files/documents/' );
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM