问题描述
我在子进程的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
的回调为止。
是什么原因造成的?如何解决?
我猜这与子进程的事件循环有关,该事件循环阻止子进程关闭直到消息为空?
https://github.com/alexkubica/promise-race-settimeout-blocking-inside-child-process
解决方法
其原因是spawnSync
直到子进程以stated in the documentation的身份完全关闭后才会返回:
child_process.spawnSync()方法通常与 child_process.spawn(),但函数不会 返回直到子进程完全关闭。 [...]
请注意,只有在事件循环的队列中有no more pending tasks时,节点脚本才会退出,在这种情况下,超时将解决超时问题。
您可以切换到spawn
来查看立即解决的promise输出:
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}`);
});