基于事件驱动;非阻塞I/O
四种I/O: 同步(synchronous)IO和异步(asynchronous)IO,阻塞(blocking)IO和非阻塞(non-blocking)IO
阻塞I/O要等数据到了才能继续,否则会阻塞用户进程
非阻塞进程中用户请求后会立即得到结果(比如如果数据没有准备好会返回error)
Google V8 引擎使用 C++ 代码编写,实现了ECMAScript 规范的第五版,可以运行在所有的主流
操作系统中,甚至可以运行在移动终端 ( 基于 ARM 的处理器,如 HTC G7等 )。V8 最早被开发用以嵌入到 Google 的开源浏览器 Chrome 中,但是 V8 是一个可以独立的模块,完全可以嵌入您自己的应用,著名的 Node.js( 一个异步的服务器框架,可以在服务端使用 JavaScript 写出高效的网络服务器 ) 就是基于 V8 引擎的。
更多关于V8的知识:http://www.ibm.com/developerworks/cn/opensource/os-cn-v8engine/
Node中的读取文件为异步I/O,和ajax数据传输道理相同,代码如下:
var fs = require(‘fs’);
fs.readFile(‘/path’, function(err, file){
console.log(“读取文件完成”);
});
Node是单线程的,不会出现死锁等问题,但会出现一下三个缺点;
1. 无法利用多核CPU
2. 错误会引起整个应用退出,应用的健壮性值得考验
3. 大量计算占用CPU导致无法继续调用异步I/O
CommonJS规范:为了弥补Javascript没有标准的缺陷
CommonJS模块规范:
1. 模块引用:var math = require(“math”);
2. 使用export导出模块
//math.js文件
export.add = function(){
//函数方法
}
使用require进行调用
//program.js文件
var math = require(‘math’);
exports.increment = function(val){
return math.add(val,1)
}
//注意上面的代码右生成了一个increament方法
模块中存在module对象,代表模块自身。Export是module的属性
3. 模块标识
即require中传进去的参数
Node中引入模块分为下面三个步骤:路径分析、文件定位、编译执行
Node中也会对模块进行缓存,缓存的是编辑和执行后的对象。会优先从缓存中加载。
模块加载时require()方法传递的四种参数:
1. 核心模块,如http/fs/path等
2. .或..开头的相对路径文件模块
3. 以/开头的绝对路径文件模块
4. 非路径形式的文件模块,如自定义的connect模块
Node中模块分为核心模块(node中自定义的)和文件模块(用户定义的)
Node中的模块编译
不同后缀名的编译方式不同。可以通过console.log(require.extension);查看已有扩展名加载方式
添加自定义的加载后缀名加载方式:require.extension[‘coffee’]
模块对象的定义代码:
function Module(id, parent){
this.id= id;
this.exports= {};
this.parent= parent;
if(parent&& parent.children){
parent.children.push(this);
}
this.filename =null;
this.loaded =false;
this.children =[];
}
为不同后缀名的文件定义编译方法:
Module._extension[‘.json’] =function(module, filename){ …… }
直接赋值形参会改变形参的引用,但不能改变作用域外的值:
var change = function(a){
a = 100;
console.log(a);// =>100
};
var a = 10;
change(a)
console.log(a);// =>10
因此如果要达到require引入一个类的效果,请赋值给module.exports对象
底层是C/C++,C/C++内建模块属于最底层的模块。