ES6标准发布后,module成为标准,标准的使用是以export指令导出接口,以import引入模块,但是在我们一贯的node模块中,我们采用的是CommonJS规范,使用require引入模块,使用module.exports导出接口。
不把require和import整清楚,会在未来的标准编程中死的很难看。
node编程中最重要的思想之一就是模块,而正是这个思想,让JavaScript的大规模工程成为可能。模块化编程在js界流行,也是基于此,随后在浏览器端,requirejs和seajs之类的工具包也出现了,可以说在对应规范下,require统治了ES6之前的所有模块化编程,即使现在,在ES6 module被完全实现之前,还是这样。
node的module遵循CommonJS规范,requirejs遵循AMD,seajs遵循CMD,虽各有不同,但总之还是希望保持较为统一的代码风格。
在Node.js中用于事件处理的event模块中,定义了一个EventEmitter类.所有可能触发的事件都是EventEmitter类子类的实例对象,EventEmitter类中的方法如下:
image.png
var http = require('http');
var server = http.createServer();
server.on('request',function (req,res) {
console.log(req.url);
res.end('hello');
});
server.listen(1337,"127.0.0.1");
当我们请求1337端口的时候输出如下所示:
/ (注解:代表程序的根目录)
/favicon.ico (注解:代表页面在收藏夹中的显示图标)
在默认情况下,针对同一事件最多可以绑定10个事件处理函数:
server.setMaxListeners(10)
用once只执行一次:
server.once('request',function (req,res) {
console.log(req.url);
res.end('hello');
});
var http = require('http');
var events = require('events');
var server = http.createServer();
server.on('request', function (req,res) {
if(req.url!='/favicon.ico'){
console.log('接收到客户端的请求');
}
});
server.on('request', function (req,res) {
if(req.url!='/favicon.ico'){
console.log(req.url);
}
res.end();
});
server.on('request', function (req,res) {
if(req.url!='/favicon.ico'){
console.log('发送响应完毕');
}
});
server.listen(1337,"127.0.0.1");
console.log(events.EventEmitter.listenerCount(server,'request'));
var http = require('http');
var server = http.createServer();
var test = function () {
server.on('request',function (req,res) {
console.log("发送了");
});
}
server.on('removeListener',function (e,f) {
console.log("对"+e+"事件取消事件处理函数");
console.log(f);
});
server.on('newListener',function (e,f) {
console.log("对"+e+"事件添加事件处理函数");
console.log(f);
});
server.on('request', function (req,res) {
if(req.url!='/favicon.ico'){
console.log('接收到客户端的请求');
}
});
server.on('request', function (req,res) {
if(req.url!='/favicon.ico'){
console.log(req.url);
}
res.end();
});
server.on('request', function (req,res) {
if(req.url!='/favicon.ico'){
console.log('发送响应完毕');
}
});
server.on('request',test);
server.removeListener('request',test);
server.listen(1337,"127.0.0.1");
事件循环定义:当线程中的I/O任务完成之后就会执行指定的回调函数,并且将这个完成的事件放在事件队列的尾部,等待事件循环,当主线程再次循环到这个事件的时候,就会直接处理并且返回给上层调用,这个过程就是事件循环(Event Loop)。Node.js运行的原理图如下所示:
image.png
这个图是整个 Node.js 的运行原理,从左到右,从上到下,Node.js 被分为了四层,分别是 应用层、V8引擎层、Node API层和LIBUV层。