Javascript 设置超时功能:Can';t将头发送到客户端后设置头
这段代码应该编写一个文件,在生成进程中运行它,然后在达到超时时终止生成进程。但是,每当它触发超时时,我都会收到一个[ERR\u HTTP\u HEADERS\u SENT]错误Javascript 设置超时功能:Can';t将头发送到客户端后设置头,javascript,node.js,express,Javascript,Node.js,Express,这段代码应该编写一个文件,在生成进程中运行它,然后在达到超时时终止生成进程。但是,每当它触发超时时,我都会收到一个[ERR\u HTTP\u HEADERS\u SENT]错误 $.get('/path', function(req, res){ // data = contents of a file fs.writeFile(filename, data, (err) => { const child_process = spawn(//run file, {detached:
$.get('/path', function(req, res){
// data = contents of a file
fs.writeFile(filename, data, (err) => {
const child_process = spawn(//run file, {detached: true});
const wait = setTimeout(function() {
try {
process.kill(-runner.pid);
return res.send("Timeout Message");
}
}, 3000);
runner.on('exit', (code, signal) => {
clearTimeout(wait);
fs.unlink(filename, (err) => {
if (code === 0) return res.send("Good");
else return res.send('Fail');
});
});
runner.stdout.on('data', function(data) {
console.log('stdout: ' + data);
});
runner.stderr.on('data', function(data) {
console.log('stderr: ' + data);
});
runner.on('error', (err) => {
clearTimeout(wait);
fs.unlink(filename, (error) => {
return res.send("Error");
});
});
});
}
谢谢你的帮助 您将两次结束请求。这就是为什么会发送
ERR\u HTTP\u HEADERS\u
代码的问题是,当达到超时时,.on('exit')
被调用,并且您再次响应,clearTimeout
此时不会执行任何操作,因为超时已经发生
解决方案是在每次res.send
前添加res.headerssend
check
runner.on('exit', (code, signal) => {
clearTimeout(wait);
fs.unlink(filename, (err) => {
if (code === 0) return !res.headersSent && res.send("Good");
else return !res.headersSent && res.send('Fail');
});
});
或者检查是否发生超时,并在exit
事件中响应,而不是在timeout
回调中响应。或者用特定的信号终止进程,然后在kill
事件上测试该信号
const wait = setTimeout(function() {
runner.kill('SIGKILL'); // Use whatever signal you prefer
}, 3000);
runner.on('exit', (code, signal) => {
clearTimeout(wait);
if(signal === 'SIGKILL')
return res.send("Timeout Message");
else if (code === 0)
return res.send("Good");
else return res.send('Fail');
fs.unlink(filename, (err) => {});
});
在一次调用中只能res.send()一次。在
exit
和setTimeout
中,终止进程仍可能触发您正在侦听的某些事件,这将导致您尝试向请求发送多个响应,而这正是触发该错误的原因。如果希望避免双重响应,则必须在计时器触发时设置一个标志,并在其他事件处理程序中检查该标志,以便在这种情况下忽略它们。实现进程非常重要。kill()
向进程发送一个信号,告诉它自行终止,该进程可以根据该信号决定要做什么。它不会直接杀死它,因此某些事件可能仍然会发生。