引子
许多运用nodejs开辟的东西都邑供应一个命令行操纵界面(CLI),这些东西在实行的历程中会及时更新实行进度或数据的下载解压缩进度等,比方10%,20%,30%…
这些信息会再终端的统一行的统一位置显现,而不是一行一行逐次打印显现……
那末其是怎样完成的?nodejs有无响应地模块供应这个功用呢?
嗯,NodeJS中有的,它就是readline模块,这个模块供应了正行数据读取写入,终端提示符位置掌握等API
完成的功用
本文章供应一个样例代码,重要申明终端提示符位置掌握题目,把须要注重的点都列在其中了
终端字符显现宽度题目
终端界面可以显现的字符地区大小题目
终端当前提示符的位置题目
终端雷同位置上内容及时更新的题目
这些题目在样例中都有触及及申明到
运用nodejs的readline模块对命令行掌握终端的提示符位置举行掌握
模仿讯问用户是不是启动运用
启动运用后及时更新运转进度信息从1%~100%,此信息显现统一行的统一个位置
代码完成
var readline = require('readline');
var util=require('util');
var inputStream=process.stdin;
var outputStream=process.stdout;
var rl = readline.createInterface({
input: inputStream,
output: outputStream,
terminal:true
});
var promptStr="MyApp> ";
//取得字符串现实长度,中文2,英文1
//掌握台中中文占用2个英笔墨符的宽度
var getDisplayLength=function(str) {
var realLength = 0, len = str.length, charCode = -1;
for (var i = 0; i < len; i++) {
charCode = str.charCodeAt(i);
if (charCode >= 0 && charCode <= 128) realLength += 1;
else realLength += 2;
}
return realLength;
};
//盘算一个字符串在当前掌握台中占用的行数和列数信息
//outputStream.rows及outputStream.columns属性为当前掌握台的显现的窗口的大写
var getStrOccRowColumns=function(str){
//str=promptStr+str;
var consoleMaxRows=outputStream.rows;
var consoleMaxColumns=outputStream.columns;
var strDisplayLength=getDisplayLength(str);
var rows=parseInt(strDisplayLength/consoleMaxColumns,10);
var columns=parseInt(strDisplayLength-rows*consoleMaxColumns,10);
return {
rows:rows,
columns:columns
}
};
//console.log(getDisplayLength(promptStr));
rl.setPrompt(promptStr);
rl.prompt();
rl.question("你想要个启动运用处置惩罚吗?", function(answer) {
rl.prompt();
rl.write(util.format('启动运用获得的复兴为:%s\r\n', answer));
//更新统一个位置显现的字符信息,每1秒更新1一次,一直到100%
var k= 0,max=100,prevOutputContent,outputContent,
cursorDx=0,cursorDy= 0,dxInfo;
//盘算
rl.prompt();
var interval=setInterval(function(){
if(k<max){
k++;
outputContent=util.format('%d% done!', k);
//将光标移动到已写入的字符前面,
readline.moveCursor(outputStream,cursorDx*-1,cursorDy*-1);
//消灭当前光标后的一切笔墨信息,以便接下来输出信息能写入到掌握台
readline.clearScreenDown(outputStream);
outputStream.write(outputContent);
//不要运用这个要领,此要领中写入的数据会被作为line事宜的输入源读取
//rl.write(outputContent);
dxInfo=getStrOccRowColumns(outputContent);
cursorDx=dxInfo.columns;
cursorDy=dxInfo.rows;
}else{
outputStream.write(util.format('\r\n'));
rl.prompt();
outputStream.write(util.format('%s\r\n',"实行完成"));
clearInterval(interval);
rl.close();
}
},100);
});
rl.on('close',function(){
process.exit(0);
});