Node.js 学习笔记 (一)

1. 异步IO

node.js是一个基于javascript的平台工具,提供在服务器端解释、运行javascript的能力。node.js底层是一套c++编写的api,同时在上层运用Google V8引擎解释javascript调用这些底层的API。

大家都知道javascript是一种单线程脚本语言,所以基于V8引擎的node.js在javascript的层面上也不例外,但很明显作为一个服务器平台工具,不可避免的是IO消耗,但也不可能因为这些IO消耗而阻塞了整个应用程序。同样是服务器工具的tomcat则使用了多线程来解决这一问题,其为每一个request开辟了一个新的线程,这样就可以尽量避免request之间的相互影响。但javascript本身是单线程的,就不可能这样运作,所以node.js使用了事件循环这一机制,提供异步IO/事件驱动来解决这一问题。

IO相关的代码就会变成如下:

resp = bigIO(); // waiting...
output(resp); // return

//Change To
bigIO(function(resp){
	output(resp);
})

正如另一篇与javascript事件循环相关的博文所述,node.js也是基于同样的模式。

在node.js中存在一个主线程和一个事件队列,主线程不断循环栈和事件队列,当处理完栈中所有方法时就会循环事件队列,如果事件队列存在需要被处理的方法就会被主线程处理,这一过程不断进行,这些被处理的方法就是事件完成之后的回调函数,而事件则会被另一个worker threads(文件、网络等IO操作,work thread由C++实现)执行,执行完成后将回调函数放置于事件队列之中。

所以node.js是一个高IO并发的服务器工具,又因为单线程的特性使其完全线程安全,同时没有线程切换所带来的开销。但也因此在CPU密集性的运算上存在着弊端,也无法充分利用多核CPU,所幸nodejs支持多进程编程,可以解决CPU密集的问题。

另外node.js第三方模块很好地支持socketio,在一些即时又不需要CPU运算的应用上存在优势。

node.js也提供了npm等lib管理工具,让开发更加便捷。


2.模块

在javascript里面并没有明确的语法定义模块(namspace),所以javascript代码往往需要使用一些编程技巧来模拟命名空间,但在node.js中其实现了commonJS的规范,让模块化更加简单。

我们可以总是可以看到如下代码

// tmp.js
exports.foo = function(){...}

// app.js
var tmp = require('./tmp.js')
tmp.foo();

node.js 为每一个js文件提供exports require module变量用于定义模块,绑定到exports上的方法将被视为公共方法,require则是导入模块,其返回的对象带有相应exports的变量。

实际上,node.js在编译js文件时,将会包装这些js文件,如下:

(function (exports, require, module, __filename, __dirname) {
    var tmp = require('./tmp.js');
    tmp.foo();
});

上文所述require会进行模块的加载,实际上是在进行文件的加载,将exports对象返回

文件加载顺序:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值