上述代码用于验证路径,必要时以错误信息终止:
// use input file name when output is a directoryif (outputInfo.isDir && outputInfo.canWrite && inputInfo.isFile) {output = path.resolve(output, path.basename(input));}// check for errorsif (!inputInfo.isFile || !inputInfo.canRead) error.push(`cannot read input file ${ input }`);if (input === output) error.push('input and output files cannot be the same');if (error.length) {console.log('Usage: ./filecompress.js [input file] [output file|dir]');console.error('\n' + error.join('\n'));process.exit(1);}
然后用readFile()
将整个文件读成一个名为content
的字符串:
// read fileconsole.log(`processing ${ input }`);let content;try {content = await readFile(input, { encoding: 'utf8' });}catch (e) {console.log(e);process.exit(1);}let lengthOrig = content.length;console.log(`file size${ lengthOrig }`);
然后JavaScript正则表达式会删除注释和空格:
// compress contentcontent = content.replace(/\n\s+/g, '\n')// trim leading space from lines.replace(/\/\/.*?\n/g, '')// remove inline // comments.replace(/\s+/g, ' ')// remove whitespace.replace(/\/\*.*?\*\//g, '')// remove /* comments */.replace(/<!--.*?-->/g, '')// remove <!-- comments -->.replace(/\s*([<>(){}}[\]])\s*/g, '$1') // remove space around brackets.trim();let lengthNew = content.length;
产生的字符串用writeFile()
输出到一个文件,并有一个状态信息展示保存情况:
let lengthNew = content.length;// write fileconsole.log(`outputting ${output}`);console.log(`file size${ lengthNew } - saved ${ Math.round((lengthOrig - lengthNew) / lengthOrig * 100) }%`);try {content = await writeFile(output, content);}catch (e) {console.log(e);process.exit(1);}
使用示例HTML文件运行项目代码:
node filecompress.js ./test/example.html ./test/output.html
Events当发生一些事情时,你经常需要执行多个函数 。比如说,一个用户注册你的app,因此代码必须添加新用户的详情到数据库中,开启一个新登录会话,并发送一个欢迎邮件 。
// example pseudo codeasync function userRegister(name, email, password) {try {await dbAddUser(name, email, password);await new UserSession(email);await emailRegister(name, email);}catch (e) {// handle error}}
这一系列的函数调用与用户注册紧密相连 。进一步的活动会引起进一步的函数调用 。比如说:
// updated pseudo codetry {await dbAddUser(name, email, password);await new UserSession(email);await emailRegister(name, email);await crmRegister(name, email); // register on customer systemawait emailSales(name, email);// alert sales team}
你可以在这个单一的、不断增长的代码块中管理几十个调用 。
Events API提供了一种使用发布订阅模式构造代码的替代方式 。userRegister()
函数可以在用户的数据库记录被创建后触发一个事件--也许名为newuser
。
任意数量的事件处理函数都可以订阅和响应newuser
事件;这不需要改变userRegister()
函数 。每个处理器都是独立运行的,所以它们可以按任意顺序执行 。
客户端JavaScript中的事件事件和处理函数经常在客户端JavaScript中使用 。比如说,当用户点击一个元素时运行函数:
// client-side JS click handlerdocument.getElementById('myelement').addEventListener('click', e => {// output information about the eventconsole.dir(e);});
在大多数情况下,你要为用户或浏览器事件附加处理器,尽管你可以提出你自己的自定义事件 。Node.js的事件处理在概念上是相似的,但API是不同的 。
发出事件的对象必须是Node.js EventEmitter
类的实例 。这些对象有一个emit()
经验总结扩展阅读
- 飞机上可以带辣椒酱吗
- 经济价值高的树种有哪些 世界十大经济树木排名榜
- 可乐鸡翅没有料酒可以用什么代替
- 芒果皮有毒吗
- 原神没有课题的答案任务是什么
- 冰箱里一定有李斯特菌吗
- 学蛋糕甜点适合在哪里学
- 3.5l的砂锅有多大
- 冻干免煮银耳羹还有营养吗?
- 红葱头的吃法