今天在写一个nodejs的服务器组件,由于配置信息需要调用者来设定,所以必须依赖某种外部输入。命令行参数传复杂的数据格式坑太多不想踩;从外部文件读取要由调用者先创建文件然后再删除会增加一些逻辑,所以也不好。最终我决定从stdin直接读取json格式的配置,因此接触到了蛋疼无比的stream.Readable。
最开始是这样写的:
var r=process.stdin;
var b=new Buffer([]);
r.on('data',function(buf){
b=Buffer.concat([b,buf]);
});
r.on('end',function(){
try{
var config=JSON.parse(b+'');
}catch(e){
// json解析失败,该报错报错
console.log(e);
process.exit();
return;
}
// 到这里终于获取到了输入stdin的配置内容。。
// TODO ...
});
然后觉得这些代码还缺少必要的错误处理,而且业务逻辑写到读取配置文件的代码段中很难看,于是又改成了下面这样:
var p=new Promise(function(resolve,reject){
var maxlen=1024; // 读入流的最大程度
var timeout=5000; // 等待读取完成的最大时间
setTimeout(function(){
reject('timeout');
},timeout);
var r=process.stdin;
var b=new Buffer([]);
r.on('data',function(buf){
b=Buffer.concat([b,buf]);
if(b.length>maxlen)reject('stdin too long');
});
r.on('end',function(){
try{
resolve(JSON.parse(b+''));
}catch(e){
reject('stdin format error');
}
});
}).then(function(config){
// 正常业务逻辑
},function(reason){
// 报错
console.log(reason);
process.exit();
});
到这里功能上已经满足了,但是每次读取流的操作都要写这一坨实在痛苦。所以我对读取的功能进行api设计,并封装成一个名为combine的模块。
我理想的调用方式如下
var combine=require('combine');
// 设定必要参数
combine({ maxlen: 1024, timeout: 5000, type: 'json' })
// 解析输入流
.parse(process.stdin)
// 解析完成
.then(function(config){
// 正常业务逻辑
},function(reason){
// 报错
});
combine.js代码见 https://www.xdelve.com/uploads/files/combine.js
相关文档
暂无
随便看看
畅言模块加载中