pro-node 之 node基础

Nodejs 基本知识,包含repl/npm/异常处理

#REPL
read eval print loop交互式窗口

  • 输入两次Ctrl+C关闭REPL,输入Ctrl+D可立即关闭REPL

  • 输入tab可显示可选项,像输入pro,按tab
    出来

    1
    2
    process
    propertyIsEnumerable
  • _,即单下划线表示上次的运算值,在chrome中是$_,python的也是_

  • 一些命令,输入.help可见
    • .load/.save 装载/保存 js文件
    • .clear|.break 一条命令没有结束时,用…表示需要更多,使用这个.break来跳出
    • .exit 退出repl

#npm

  • npm install package@version

    • -g全局安装,有些工具箱gulp mocha stylus等node cli工具需要全局安装
    • @version可以明确指定,也可以用范围描述,如@”>1.2.3” : 大于1.2.3版本
    • --save,保存到package.json的dependency字段
    • 简写npm i xxx
  • npm link
    这个特别有用,你在开发一个package b,在d:\node\proj\b\目录下
    你希望测试一下,你可以使用管理员账号,在b目录,运行npm link,将这个目录link至global目录
    然后再使用的地方,运行命令行npm link b,就相当于npm install b

  • npm unlink逆向操作

  • npm update package_name 更新包

  • npm rm package_name 删除包

  • npm publish发布包,.npmignore表示忽略的文件

require(‘path’)
path以./ ../开头的,表示相对路径
require.resolve()解析一个包的位置
每个文件的module.exports代表着require的返回值,默认是空的object,

module的其他字段

字段 说明
id 表示模块的id
filename 表示模块解析得到的全路径
loaded 表示是否已经加载
parent 加载该模块的模块,就是调用require的模块
children 与parent对应

#error handle异常处理

##try catch
同步js代码,使用try catch finally来捕捉异常,但不适用于异步代码

1
2
3
4
5
6
7
8
9
10
11
12
var fs = require('fs');
try {
fs.readFile("", "utf8", function(error, data) {
if (error) {
throw error;
}
console.log(data);
});
}
catch(ex){
console.log("已捕捉到异常...");
}

这段代码,readFile,路径为空,在执行回调的时候,第一个参数代表着错误,但这个回调已经不再try catch的stack里面执行,捕捉不到异常,没有设置process.on("uncaughtException",callback),导致程序crash掉

##domain
pro-node书中解释是:

domain : allow multiple I/O operations to be grouped into a single unit. When a timer, event emitter
(covered in Chapter 4), or callback function registered with a domain creates an error, the domain is notified so the
error can be handled appropriately.

允许将callback,timer,event emmiter归为一组,发生错误时触发domin的error事件

  • 在domain.run里面运行的回调函数,setTimeout的timer,event_emmiter全部绑定到当前domin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var domain = require('domain').create();
var fs = require('fs');

domain.run(function(){
fs.readFile("not-exist",'utf8',function(err,data){
if(err) throw err;

console.log(data);
domain.dispose();
});
});

domain.on('error',function(err){
console.log("捕捉到异常...");
console.log(err);
});
  • domain.add(timerId)显式添加timer
  • domain.bind显式添加回调函数,如下改写示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var domain = require('domain').create();
var fs = require('fs');

//显式bind callback
fs.readFile("not-exist",'utf8',domain.bind(function(err,data){
if(err) throw err;

console.log(data);
domain.dispose();
}));

domain.on('error',function(err){
console.log("捕捉到异常...");
console.log(err);
});
  • domain.intercept
    intercept 字面意思是 拦截,此方法回拦截错误,其他方面与bind相同,如下改写
1
2
3
4
5
6
7
8
9
10
11
12
var domain = require('domain').create();
var fs = require('fs');

fs.readFile("not-exist",'utf8',domain.intercept(function(data){
console.log(data); //不用自己判断err了
domain.dispose();
}));

domain.on('error',function(err){
console.log("捕捉到异常...");
console.log(err);
});
  • domain.dispose() 不需要这个domain时,使用dispose销毁