0%

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
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
16
17
18
19
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
13
14
15
16
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 销毁