node.js等待文件操作完成
我是node.js的新手,我需要编写一个web服务器来获取数据并将其写入文件。然后,该文件将在外部程序中使用 我的问题是node.js在数据完全写入文件之前执行外部程序。如何在执行外部程序之前等待它完成node.js等待文件操作完成,node.js,web-services,asynchronous,Node.js,Web Services,Asynchronous,我是node.js的新手,我需要编写一个web服务器来获取数据并将其写入文件。然后,该文件将在外部程序中使用 我的问题是node.js在数据完全写入文件之前执行外部程序。如何在执行外部程序之前等待它完成 var http = require('http') var map = require('through2-map') var fs = require('fs') var str = "" var sh = require('execSync'); var tmp_filename = ""
var http = require('http')
var map = require('through2-map')
var fs = require('fs')
var str = ""
var sh = require('execSync');
var tmp_filename = ""
function random (low, high) {
return Math.random() * (high - low) + low;
}
function execute_program(){
var command = 'ruby ' + __dirname + '/check_content.rb --file '+ tmp_filename
var result = sh.exec(command);
console.log('return code ' + result.code);
console.log('stdout + stderr ' + result.stdout);
return result.stdout
}
function write_to_file (chunk){
str = chunk.toString();
fs.appendFile(tmp_filename, str, function (err){
if (err) throw err;
console.log('The "data to append" was appended to file!');
}
)
}
var server = http.createServer( function(req, res){
tmp_filename = '/tmp/tmp_template_' + random(1000, 99999) + '.template'
res.writeHead(200, {'Content-Type': 'text/plain'});
message = req.pipe(map(function (chunk, res) {
write_to_file(chunk);
}))
var out = execute_program();
res.write(out)
message.pipe(res)
}
)
server.listen(8000)
注意:我不确定你想用res.write(out)
和message.pipe(res)
做什么。这将把ruby脚本的输出写入响应,然后看起来您正在将请求主体管道化。实际上,message.pipe(res)
行不起作用,因为您将尝试从可写流进行管道传输,而这是无法做到的对于这个答案,我假设您不想要消息.pipe(res)
行;如果我错了,请纠正我。
简单/快速回答
最简单的答案是侦听req
上的end
事件,然后在该事件触发时执行程序,等等:
var server = http.createServer( function(req, res){
tmp_filename = '/tmp/tmp_template_' + random(1000, 99999) + '.template'
res.writeHead(200, {'Content-Type': 'text/plain'});
req.on('end', function() {
var out = execute_program();
res.write(out);
res.end();
});
req.pipe(map(function (chunk, res) {
write_to_file(chunk);
}));
}
)
优化:
您还可以使用fs.createWriteStream()
,而不是使用fs.appendFile()
附加块。这看起来像:
var server = http.createServer( function(req, res){
tmp_filename = '/tmp/tmp_template_' + random(1000, 99999) + '.template'
res.writeHead(200, {'Content-Type': 'text/plain'});
req.on('end', function() {
var out = execute_program();
res.write(out);
res.end();
});
req.pipe(fs.createWriteStream(tmp_filename));
}
)
有了它,您就可以删除整个write_to_file
函数
这也将防止一个问题,你可能会有,如果你碰巧得到相同的随机数为您的临时文件;使用当前代码,您将附加到现有文件,这可能不是您想要的。如果出于某种原因,您确实希望在这种情况下附加到文件,您可以将
a
标志(用于附加)传递到fs.createWriteStream
:fs.createWriteStream(tmp_文件名,{flags:'a'})代码>谢谢Mike S。message.pipe(res)和res.write(out)是多余的…但是我做了一些研究并使用了async.瀑布包,下面的内容对我有用。但我会接受你的优化建议
var http = require('http');
var map = require('through2-map');
var fs = require('fs');
var str = "";
var sh = require('execSync');
var async = require('async');
var tmp_filename = "";
function random (low, high) {
return Math.random() * (high - low) + low;
}
function write_to_file (chunk){
str = chunk.toString();
fs.appendFile(tmp_filename, str, function (err){
if (err) throw err;
console.log('The "data to append" was appended to file!');
}
)
}
function execute_program(){
var command = 'ruby ' + __dirname + '/check_content --file ' + tmp_filename
var result = sh.exec(command);
console.log('return code ' + result.code);
console.log('stdout + stderr ' + result.stdout);
return result.stdout
}
async.waterfall([
function(callback){
var server = http.createServer(function(req, res){
callback(null, req, res)
}
).listen(8000);
},
function(req, res, callback){
tmp_filename = '/tmp/tmp_template_' + random(1000, 99999) + '.template'
var message = req.pipe(map(function (chunk) {
write_to_file(chunk);
}))
setTimeout(function () {
callback(null, req, res, message);
}, 666);
},
function(req, res, message, callback){
var out = execute_program()
res.write(out)
message.pipe(res)
callback(null, 'done');
}
])
我想你的整个问题归结为:如何通知我完成req.pipe
?是吗?正确,我需要提取发送的所有数据,并将其写入代码部分的文件中。