菜鸟教程Node.js笔记
教程地址:http://www.runoob.com/nodejs/nodejs-tutorial.html。
npm更新npm
见http://www.runoob.com/nodejs/nodejs-npm.html。
npm install npm -g
回调函数
见http://www.runoob.com/nodejs/nodejs-callback.html。
回调函数在完成任务后就会被调用,Node 使用了大量的回调函数,Node 所有 API 都支持回调函数。
下面是一段非阻塞代码:
var fs = require("fs");
fs.readFile('input.txt', function (err, data) {
if (err)
console.error(err);
else
console.log(data.toString());
});
console.log("程序执行结束!");
以上代码执行结果如下:
$ node main.js
程序执行结束!
菜鸟教程官网地址:www.runoob.com
可以这样认为:整个程序有运行在主线程之中,但是主线程之外还有一个IO线程池,而fs.readFile
相当于把读文件的任务放入线程池(这个线程池也可能只是一个线程)中,然后就返回了(所以这是一个异步的任务),当IO结束后,主线程找个时机执行回调函数。
domain模块
见http://www.runoob.com/nodejs/nodejs-domain-module.html。
示例太大,不易分析。
示例1
var EventEmitter = require("events").EventEmitter;
var domain = require("domain");
var emitter1 = new EventEmitter();
// 创建域
var domain1 = domain.create();
domain1.on('error', function(err){
console.log("domain1 处理这个错误 ("+err.message+")");
});
// 显式绑定
domain1.add(emitter1);
emitter1.on('error',function(err){
console.log("监听器处理此错误 ("+err.message+")");
});
emitter1.emit('error',new Error('通过监听器来处理'));
输出:
监听器处理此错误 (通过监听器来处理)
示例2
var EventEmitter = require("events").EventEmitter;
var domain = require("domain");
var emitter1 = new EventEmitter();
// 创建域
var domain1 = domain.create();
domain1.on('error', function(err){
console.log("domain1 处理这个错误 ("+err.message+")");
});
// 显式绑定
domain1.add(emitter1);
emitter1.on('error',function(err){
console.log("监听器处理此错误 ("+err.message+")");
});
emitter1.emit('error',new Error('通过监听器来处理')); // 监听器处理此错误 (通过监听器来处理)
// 删除了listener
emitter1.removeAllListeners('error');
// 没有监听器了,所以domain1会去处理
emitter1.emit('error',new Error('通过 domain1 处理')); // domain1 处理这个错误 (通过 domain1 处理)
输出:
监听器处理此错误 (通过监听器来处理)
domain1 处理这个错误 (通过 domain1 处理)
示例3
若domain没有接手emitter的错误处理,那么程序将崩溃,我们在示例2的基础上再加2行:
var EventEmitter = require("events").EventEmitter;
var domain = require("domain");
var emitter1 = new EventEmitter();
// 创建域
var domain1 = domain.create();
domain1.on('error', function(err){
console.log("domain1 处理这个错误 ("+err.message+")");
});
// 显式绑定
domain1.add(emitter1);
emitter1.on('error',function(err){
console.log("监听器处理此错误 ("+err.message+")");
});
emitter1.emit('error',new Error('通过监听器来处理')); // 监听器处理此错误 (通过监听器来处理)
// 删除了listener
emitter1.removeAllListeners('error');
// 没有监听器了,所以domain1会去处理
emitter1.emit('error',new Error('通过 domain1 处理')); // domain1 处理这个错误 (通过 domain1 处理)
domain1.remove(emitter1);
emitter1.emit('error', new Error('转换为异常,系统将崩溃!'));
运行结果如下:
监听器处理此错误 (通过监听器来处理)
domain1 处理这个错误 (通过 domain1 处理)
events.js:141
throw er; // Unhandled 'error' event
^
Error: 转换为异常,系统将崩溃!
at Object.<anonymous> (/home/letian/Desktop/nodejs-code/test.js:29:24)
at Module._compile (module.js:434:26)
at Object.Module._extensions..js (module.js:452:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:475:10)
at startup (node.js:118:18)
at node.js:952:3
示例4
上面的三个示例都是domain显示绑定emitter,下面的示例是隐式绑定:
var EventEmitter = require("events").EventEmitter;
var domain = require("domain");
var domain2 = domain.create();
domain2.on('error', function(err){
console.log("domain2 处理这个错误 ("+err.message+")");
});
// 隐式绑定
domain2.run(function(){
var emitter2 = new EventEmitter();
emitter2.emit('error',new Error('通过 domain2 处理'));
});
运行结果:
domain2 处理这个错误 (通过 domain2 处理)