手记

node学习笔记

传参

Node约定,如果某个函数需要回调函数作为参数,则回调函数是最后一个参数。另外,回调函数本身的第一个参数,约定为上一步传入的错误对象。

var callback = function (error, value) {
  if (error) {
    return console.log(error);
  }
  console.log(value);
}

上面代码中,callback的第一个参数是Error对象,第二个参数才是真正的数据参数。这是因为回调函数主要用于异步操作,当回调函数运行时,前期的操作早结束了,错误的执行栈早就不存在了,传统的错误捕捉机制try…catch对于异步操作行不通,所以只能把错误交给回调函数处理。

如果没有发生错误,回调函数的第一个参数就传入null。这种写法有一个很大的好处,就是说只要判断回调函数的第一个参数,就知道有没有出错,如果不是null,就肯定出错了。另外,这样还可以层层传递错误。

fs.readFile('/foo.txt', function(err, data) {
  if (err !== null) throw err;
  console.log(data);
});

function async2(continuation) {
  setTimeout(function() {
    try {
      var res = 42;
      if (true)
        throw new Error("woops!");
      else
        continuation(null, res); // pass 'null' for error
    } catch(e) {
      continuation(e, null);
    }
  }, 2000);
}

async2(function(err, res) {
  if (err)
    console.log("Error: (cps) failed:", err);
  else
    console.log("(cps) received:", res);
});
// Error: (cps) failed: woops!
全局对象

global:声明 var x = 1 , global.x 等于 undefined

全局变量

__filename:指向当前运行的脚本文件名

__dirname:指向当前运行脚本所在目录

核心模块

http:提供HTTP服务器功能
url:解析URL
fs:与文件系统交互
querystring:解析URL的查询字符串
util:提供一系列实用小工具
path:处理文件路径

异常处理

Node是单线程运行环境,一旦抛出的异常没有被捕获,就会引起整个进程的崩溃。所以,Node的异常处理对于保证系统的稳定运行非常重要。

一般来说,Node有三种方法,传播一个错误。

1.使用throw语句抛出一个错误对象,即抛出异常。

2.将错误对象传递给回调函数,由回调函数负责发出错误。

3.通过EventEmitter接口,发出一个error事件。

unhandledRejection事件

用来监听没有捕获的Promise对象的rejected状态。

var promise = new Promise(function(resolve, reject) {
  reject(new Error("Broken."));
});

promise.then(function(result) {
  console.log(result);
})

上面代码中,promise的状态变为rejected,并且抛出一个错误。但是,不会有任何反应,因为没有设置任何处理函数。

只要监听unhandledRejection事件,就能解决这个问题。

process.on('unhandledRejection', function (err, p) {
  console.error(err.stack);
})
EventEmitter 类
//event.js 文件
var EventEmitter = require('events').EventEmitter; 
var event = new EventEmitter(); 
event.on('some_event', function() { 
    console.log('some_event 事件触发'); 
}); 
setTimeout(function() { 
    event.emit('some_event'); 
}, 1000); 

自定义一个事件,通过event.emit调用

大多数时候我们不会直接使用 EventEmitter,而是在对象中继承它。包括 fs、net、 http 在内的,只要是支持事件响应的核心模块都是 EventEmitter 的子类。

为什么要这样做呢?原因有两点:

首先,具有某个实体功能的对象实现事件符合语义, 事件的监听和发生应该是一个对象的方法。

其次 JavaScript 的对象机制是基于原型的,支持 部分多重继承,继承 EventEmitter 不会打乱对象原有的继承关系。

1人推荐
随时随地看视频
慕课网APP