Electron+Python后端:如何实现JS与Python的重复数据传递
解决Electron中JS与Python进程间重复传值的问题
看起来你踩了两个常见的坑:一是过早关闭了stdin流导致后续无法写入,二是Python脚本只读取了一次输入就一直循环旧内容。我来帮你一步步解决这个问题:
错误原因分析
你遇到的ERR_STREAM_WRITE_AFTER_END错误,是因为第一次点击按钮时调用了childShellProcess.stdin.end()——这个操作会直接关闭Python进程的标准输入流,之后再尝试往里面写数据自然就会报错。另外,你的Python脚本只在启动时读取了一次输入,之后不管JS传什么新值,它都会一直输出最初的Some Text。
修改后的解决方案
1. JavaScript端代码调整
核心是不要关闭stdin流,并且每次传值时加上换行符(因为Python的readline()是按行读取的):
const {PythonShell} = require('python-shell'); function testSpawn(evt){ let sendText; if (evt.srcElement.id === "btnSpawnProcess"){ sendText = 'Some Text'; } else if (evt.srcElement.id === "btnEditProcess"){ sendText = 'Some Other Text'; } // 写入数据并添加换行,确保Python能正确读取 childShellProcess.stdin.write(`${sendText}\n`); } var options = {mode: 'json'}; var shellProcess = new PythonShell('./model/testSpawn.py', options); childShellProcess = shellProcess.childProcess; // 统一监听Python的输出 shellProcess.on('message', function (message) { console.log(message); }); document.addEventListener('DOMContentLoaded', function() { document.getElementById("btnSpawnProcess").addEventListener("click", testSpawn); document.getElementById("btnEditProcess").addEventListener("click", testSpawn); });
2. Python端代码调整
需要改成持续监听stdin输入,而不是只读取一次。这里提供两个版本:
版本1:顺序处理(等当前100次输出完再切换新内容)
import sys import json import time # 循环读取stdin的每一行输入 for message in sys.stdin: # 去除换行符和空白字符 message = message.strip() if not message: continue # 输出当前接收到的消息100次 for _ in range(100): print(json.dumps(message, ensure_ascii=False)) sys.stdout.flush() time.sleep(1)
版本2:立即切换(点击按钮后马上输出新内容)
如果想要点击第二个按钮后立即停止输出旧内容,改用新内容,可以用线程实现:
import sys import json import time import threading current_message = None is_running = True def output_thread(): global current_message while is_running: if current_message is not None: print(json.dumps(current_message, ensure_ascii=False)) sys.stdout.flush() time.sleep(1) # 启动后台输出线程 threading.Thread(target=output_thread, daemon=True).start() # 持续读取输入并更新当前消息 for message in sys.stdin: message = message.strip() if message: current_message = message # 当输入流关闭时停止线程 is_running = False
关键要点总结
- 不要随意调用
stdin.end(),保持输入流打开才能重复传值; - JS传值时必须加换行符
\n,否则Python无法通过逐行读取获取新内容; - Python脚本要持续监听stdin,而不是只读取一次初始输入。
内容的提问来源于stack exchange,提问作者rw_dev
相关产品推荐
相关产品推荐

