javascript - ElectronJS : logging method fires multiple times when don't wanted when using invoke/handle

标签 javascript electron invoke handle

如标题所述。我的ElectronJS项目有这个问题。当我尝试记录调用的处理程序的输出时,即使函数仅运行一次,记录也会发生多次。这可能是什么原因?
对于创建的每个类对象,该函数仅运行一次。请参阅底部的GIF,以查看“实际中”的问题。
我试过删除处理程序和监听器,但是这样做只是为了使下一个对象无法调用downloadPoster
在此先感谢您的帮助。
这是实例化和“处理”对象的方式。

// On drop
window.ondrop = async function(e) {
    e.preventDefault();
    body.classList.remove('file-hover');
    for (var [i, file] of Object.entries(e.dataTransfer.files)) {
        var x = new Movie(file.path);
        await x.process();
    }
    return false;
};

这是renderer.js中的类的函数
/**
* Download poster file for movie
*/
async downloadPoster() {

    // This is the url used to search for the poster we want
    var searchUrl = new URL(Config.api.searchUrl);
    searchUrl.search = new URLSearchParams({
        page: 1, 
        api_key: Config.api.key,
        query: this.#movie.tags.title,
        year: this.#movie.tags.year
    });

    // Search for poster in the main thread
    await axios.get(searchUrl.href)
    .then(async (resp) => {

        // No results
        if (resp.data.total_results <= 0) {
            this.log('No poster found', 'error');
            return;
        } 
            
        // Invoke poster download
        const result = await ipcRenderer.invoke('downloadPoster', {
            src: Config.api.posterUrl + resp.data.results[0].poster_path,
            dest: path.join(this.#movie.new.absolutePath, Config.api.posterFilename)
        })
        
        // This shows "undefined"    
        this.log(result);

    })
    .catch(async (err) => {
            this.log('Could not search for poster: ' + err, 'error');
    });

} 
这是main.js中的处理函数
// Download poster
ipcMain.handle('downloadPoster', async (event, args) => {

    await axios.get(args.src, { responseType: 'stream' })
    .then(async (resp) => {

        const writeStream = fs.createWriteStream(args.dest);

        // Write data to file
        await resp.data.pipe(writeStream);
        
        // When finished, send reply back
        writeStream.on('finish', async () => {
            return {
                success: true,
                message: 'Poster downloaded'
            }
        });

        // On error writing, send reply back
        writeStream.on('error', async (err) => {
            return {
                success: false,
                message: 'Could not write poster to file: ' + err
            }
        });

    })
    .catch(async (err) => {
        return {
            success: false,
            message: 'Could not download poster: ' + err
        }
    });

});
No actual pirated material. Just test folders.

最佳答案

您可能会误解invoke/handle。使用该功能的全部要点是,主进程中处理程序的返回值由渲染器中的invoke方法返回。因此,您可以执行以下操作:

// main.js
ipcMain.handle('some-command', async (evt, data) => {
// do something with data, the handler can also be async
 const value = await getSomeValue();
 return doSomething(data, value);
}
// renderer.js
(async () => {
 const invokeReturn = await ipcRenderer.invoke('some-command', data);
 // invokeReturn will contain the result of doSomething(data, value) from main
})
我需要对您的代码进行一些调试以确保,但是我的直觉是行为是由以下这段代码引起的:
// Poster download reply from the invoke above
ipcRenderer.on('downloadPosterReply', async (event, args) => {
您正在设置一个监听器,并且从不删除它,因此每次调用函数时,都会添加一个新的处理程序,从而导致越来越多的日志出现。多亏了invoke/handle,您根本不需要在这里使用on处理程序。

关于javascript - ElectronJS : logging method fires multiple times when don't wanted when using invoke/handle,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65799590/

相关文章:

javascript - 切换可见性不起作用 (HTML/CSS/Javascript)

javascript - 在点击此链接后,在绑定(bind)到 anchor 链接的 onclick 函数内获取 URL/ anchor

javascript - Selenium Webdriver 处理弹出窗口

angular - 低质量 Angular Electron 屏幕截图

c# - 两个WinForm之间的TreeView的Invoke方法应该在哪里处理?

c# - InvokeRequired 是必需的吗?

javascript - 字符串结尾正则表达式匹配太慢

push-notification - Electron 推送通知

node.js - 我们可以从 Node js 应用程序或命令提示符中获取 vscode 的 Electron 版吗

.net - 以编程方式对 TextBox 调用验证