Node.js 调用可执行文件时的 stdout 缓冲区问题

Node.js 调用其他语言编译出来的可执行文件是非常常见的场景。

但只要涉及到「实时输出」,一个经典的坑是:缓冲区。

一、swift+node错误示例

swift

swift 复制代码
import Darwin

print("Hello")
sleep(2)
print("World")

正常输出

复制代码
Hello
(停 2 秒)
World

打包为可执行文件

shell 复制代码
swiftc helloworld.swift -o helloworld

node调用

js 复制代码
import { exec } from 'child_process';

exec('./helloworld', (err, stdout) => {
  console.log(stdout);
});

结果,2秒后全部输出,而不是先输出Hello等2秒才到World。

复制代码
(停 2 秒)
Hello
World

二、修复

swift关闭缓冲

swift 复制代码
import Darwin

setbuf(stdout, nil) // 关闭缓冲

print("Hello")
sleep(2)
print("World")

node调用

之前的exec适合一次性调用。可以改为spawn更适配流式实时。

js 复制代码
import { spawn } from 'child_process';

const p = spawn('./helloworld');

p.stdout.on('data', data => {
  process.stdout.write(data);
});

另外一种正确写法

js 复制代码
import { spawn } from 'child_process';

spawn('./helloworld', {
  stdio: 'inherit'
});

输出结果,表现正常

复制代码
Hello
(停 2 秒)
World
相关推荐
一点一木5 小时前
深度体验TRAE SOLO移动端7天:作为独立开发者,我把工作流揣进了兜里
前端·人工智能·trae
天外飞雨道沧桑6 小时前
TypeScript 中 omit 和 record 用法
前端·javascript·typescript
Lee川6 小时前
mini-cursor 揭秘:从 Tool 定义到 Agent 循环的完整实现
前端·人工智能·后端
canonical_entropy7 小时前
从 Spec-Driven Development 到 Attractor-Guided Engineering
前端·aigc·ai编程
研☆香7 小时前
聊聊前端页面的三种长度单位
前端
给钱,谢谢!8 小时前
React + PixiJS 实现果园成长页:从状态机到浇水动画
前端·react.js·前端框架
暗冰ཏོ9 小时前
VUE面试题大全
前端·javascript·vue.js·面试
次元工程师!9 小时前
LangFlow开发(三)—Bundles组件架构设计(3W+字详细讲解)
java·前端·python·低代码·langflow
Bug-制造者10 小时前
现代Web应用全栈开发:从架构设计到部署落地实战
前端
青春喂了后端10 小时前
IntelliGit 前端状态层重构:把一个全局 Store 拆成清晰的状态边界
前端·重构·状态模式