Node.js中如何等待Python子进程返回结果后再执行后续代码?
Node.js调用Python脚本异步问题解决
你的问题核心是Node.js的异步特性导致的——spawn启动Python子进程后,不会等待子进程输出结果,而是直接执行后续的if判断逻辑,这时候images_score还是初始值0,所以会进入else分支输出'err'。
以下是两种可行的解决方案:
方案1:将逻辑移到事件回调中
把依赖Python输出的判断逻辑放到stdout的data事件或者子进程的close事件回调里,确保拿到结果后再执行:
var images_score = 0 const python = spawn('python',[__dirname + "/car_detect/main.py", img_name]); // 监听子进程输出 python.stdout.on('data', (data) => { images_score = Number(data.toString().trim()); // 去除可能的换行/空格 console.log(images_score); }); // 监听子进程退出事件,确保输出完全接收后处理逻辑 python.on('close', (code) => { if (code === 0) { // 子进程正常退出 if (images_score === 1) { // 这里写你的业务代码 } else { console.log('err'); } } else { console.log(`Python脚本异常退出,退出码:${code}`); } }); // 监听Python脚本的错误输出 python.stderr.on('data', (data) => { console.error(`Python脚本错误:${data.toString()}`); });
方案2:用Promise封装+async/await(推荐)
通过Promise将异步操作封装,配合async/await让代码逻辑更清晰,像同步代码一样执行:
const { spawn } = require('child_process'); // 封装调用Python脚本的Promise函数 function callPythonCarDetect(imgName) { return new Promise((resolve, reject) => { const pythonProcess = spawn('python', [__dirname + "/car_detect/main.py", imgName]); let output = ''; // 收集标准输出 pythonProcess.stdout.on('data', (chunk) => { output += chunk.toString(); }); // 捕获错误输出 pythonProcess.stderr.on('data', (errorChunk) => { reject(new Error(`Python脚本执行出错:${errorChunk.toString()}`)); }); // 子进程退出时处理结果 pythonProcess.on('close', (exitCode) => { if (exitCode === 0) { // 去除输出中的空白字符后转数字 resolve(Number(output.trim())); } else { reject(new Error(`Python脚本退出码:${exitCode}`)); } }); }); } // 使用async/await调用 async function handleImageDetection(imgName) { try { const images_score = await callPythonCarDetect(imgName); console.log(images_score); if (images_score === 1) { // 这里写你的业务逻辑 } else { console.log('err'); } } catch (err) { console.error(err.message); } } // 执行处理函数 handleImageDetection(img_name);
注意事项
- Python脚本的输出可能包含换行符或空格,一定要用
trim()处理后再转换为数字,避免因格式问题导致判断错误 - 务必监听
stderr事件,捕获Python脚本运行时的错误,方便排查问题 - 优先使用
close事件处理结果,因为当Python输出内容较大时,data事件可能会分多次触发,close事件能确保所有输出都已接收完毕
内容的提问来源于stack exchange,提问作者younes_khosravi
相关产品推荐
相关产品推荐

