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
相关推荐
蜗牛攻城狮3 分钟前
CSS中的 `dvh` 与 `vh`: 深入理解视口单位
前端·css
啥都不懂的小小白9 分钟前
Shell脚本编程入门:从零基础到实战掌握
前端·shell
东东51626 分钟前
校园短期闲置资源置换平台 ssm+vue
java·前端·javascript·vue.js·毕业设计·毕设
qq_4198540527 分钟前
富文本编辑器
前端
悟能不能悟27 分钟前
VUE的国际化,怎么实现
前端·javascript·vue.js
Mr Xu_32 分钟前
解决 Vue + Axios 热更新导致响应拦截器重复注册的问题
前端·javascript·vue.js
lichenyang45339 分钟前
Node.js AI 开发入门 - 完整学习笔记
人工智能·学习·node.js
岁岁种桃花儿43 分钟前
NodeJs从入门到上天:什么是Node.js
前端·node.js
colicode1 小时前
语音报警接口开发参考:紧急情况下快速调用语音API发送安全警报
前端·语音识别
夏河始溢1 小时前
一八四、Zustand 状态管理详解、与 Redux、MobX 的对比分析
前端·javascript·react.js·状态管理·zustand