我正在尝试允许用户以csv格式导出他们的联系人列表。我对如何运行export_connect_csv()函数感到困惑。我应该将其放在子进程或process.nextTick中吗?
function export_connect_csv(user_id, file_location){
mysqlPool.getConnection(function(err, connection){
var csv_row = "Email,First Name,Last Name,Status,Created\n";
function processRow (row) {
var csv_row = row.email+','+row.first_name+','+row.last_name+','+row.status+','+row.created+"\n";
fs.appendFile(file_location, csv_row, function (err) {
if(err){
throw err;
}
});
}
fs.appendFile(file_location, csv_row, function (err) {
if(err){
throw err;
}
var query = connection.query('SELECT * FROM contacts where user_id = "'+user_id+'"');
query
.on('error', function(err) {
//handle error
})
.on('fields', function(fields) {
})
.on('result', function(row) {
processRow(row);
})
.on('end', function() {
//email now
console.log('done');
});
});
});
}
var exportContacts = function(req, res){
var user_id = req.params.user_id || 0;
export_connect_csv(user_id);
res.json({});
};
最佳答案
您不需要使用任何一个,只需调用该函数即可。所有这些代码都将异步运行,即getConnection和fs.appendFile。但是,如果两个用户尝试同时导出,则会遇到冲突。您有以下选择:
1)每次调用该函数时,您传递一个唯一的file_name
2)您可以保持原样,并使用fs.appendFileSync确保它们不会相互重叠,但这会阻止您
3)也许最好的解决方案是使用Process.nextTick进行预期的操作,但是应该使用setImmediate和appendFileSync来同步来自多个用户的写入操作(一次只写一行,以避免阻塞长时间):
setImmediate(function(){
fs.appendFileSync('文件名',JUST_A_SINGLE_ROWW)
});
这是因为递归process.nextTick可能会饿死事件循环并有效地阻止您(因此使用setImmediate),并且您需要使用fs.appendFileSync,因为两个用户可能会同时写入同一文件。
有关setImmediate与nextTick的更多信息:
setImmediate vs. nextTick
有关appendFile的更多信息:http://nodejs.org/api/fs.html#fs_fs_appendfile_filename_data_options_callback