node.js - setTimeout 在子进程中阻止 Promise
问题描述
setTimeout
我在子进程的承诺内部遇到了一个奇怪的问题。
这些是我的文件:
index.js
:
const {spawnSync} = require('child_process');
const {resolve} = require('path');
const timeoutPromiseModule = resolve(__dirname, '.', 'timeout-promise');
const {stdout} = spawnSync('node', [timeoutPromiseModule]);
console.log(stdout.toString());
timeout-promise.js
:
Promise.race([
Promise.resolve(),
new Promise((resolve, reject) => {
setTimeout(() => {reject('too long')}, 10000);
})
])
.then(x=> console.log('resolved'))
.catch(e => console.log('rejected'));
当我运行时,node index.js
我希望输出会立即打印,但实际发生的是输出挂起,直到setTimeout
子进程调用 的回调。
这是什么原因造成的,如何解决?
我猜这与子进程的事件循环有关,它阻止子进程关闭直到消息为空?
为方便起见,我将代码上传到 GitHub:
https://github.com/alexkubica/promise-race-settimeout-blocking-inside-child-process
解决方案
原因是spawnSync
在子进程完全关闭之前不会返回,如文档中所述:
child_process.spawnSync() 方法通常与 child_process.spawn() 相同,只是该函数在子进程完全关闭之前不会返回。[...]
请注意,仅当事件循环的队列中没有更多待处理任务时,节点脚本才会退出,在这种情况下,会在超时解决后发生。
您可以切换到spawn
查看立即解决的承诺输出:
const res = spawn('node', [timeoutPromiseModule]);
res.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
res.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});
推荐阅读
- python-3.x - how to best iterate through dictionary keys and compare the values?
- ember.js - 因 FindRecord 失败而中止转换
- python - 检查是否有错误
- r - Tidyr:pivot_wider 错误:无法转换
到 - php - Laravel-livewire:为什么触发事件会执行 render() 方法?
- python - tesseract 根本不准确,即使有配置
- windows - PowerShell 未启动
- autodesk-forge - Forge Viewer 错误 CORS 策略:请求的资源上不存在“Access-Control-Allow-Origin”标头
- javascript - 如何修复 npx 在终端上创建 React 启动屏幕?
- html - 在分词多行时修剪给定空间的字符串