首页 > 代码库 > nodejs 编程建议(代码规范)

nodejs 编程建议(代码规范)

 

1. 不要使用 "try ... catch" ,因为nodejs都是异步操作,try catch无法捕捉回调里面的异常,除非你在回调里面也写try catch

try...catch statement cannot catch the error in callback. Here is an example:
fs = require('fs');


try {
  fs.stat('doesnt_exist.txt', function(err, stats) {
    if (err) {
      throw err;
    }
    console.log('data', stats);
  });
}
catch (e) {
  console.error('error statting');
}

这里的错误不会被捕捉。

解决方案


  1. 把数据库查询或者文本读取的try catch改为处理回调函数里面的第一个参数err,因为这些操作如果出错在nodejs里面是不会跑出异常而是返回一个err对象
  2. 使用forever https://github.com/nodejitsu/forever 这样进程挂掉就会被立马再次启动起来,记得设置 spinSleepTime !否则你的程序在1s内挂两次就再也启动不起来了
  3. 官方建议使用domain对象,如果是使用express的朋友可以直接使用 express-domain-middleware,这个插件有几个好处
    a 捕获系统中所有的异常,并且可以自己定义出错的解决逻辑
    b 在所有的流程中都会增加一个requestid,可以通过这个id在日志中体现出一个请求所经过的流程,解决了异步操作通过日志无法识别某个请求的问题
其实还有一种解决方案是不推荐的(官方也极力反对)
process.on('uncaughtException', function(err) {
  console.error(err.stack);
});

这个方法在捕捉未考虑到的异常方面,万无一失,但是对于程序来说不是一个好习惯,我也不推荐


2. 避免使用 this 和 new

因为 Node.js 传递很多回调和有很多高阶函数,所以你要博阿正你的程序能在别的地方被调用的时候不会出问题,尽量不要用跟上下文相关的 this 和 new



3. 更小的函数块

尽量不要陷入“回调地狱”,让函数更小
// 一个回调嵌套回调的例子


function convertJsonToCsv(filename, target, callback) {
    readFile(filename, function (err, content) {
        if (err) {
            return callback(err);
        }
        parseJson(content, function (err, data) {
            if (err) {
                return callback(err);
            }
            convertToCsv(data, function (err, csv) {
                if (err) {
                    return callback(err);
                }
                writeFile(target, csv, callback);
            });
        });
    });
}




// 切分成小块之后


function convertJsonToCsv(filename, target, callback) {readJsonFile(filename, function (err, data) {if (err) { return callback(err); }writeCsvFile(target, data, callback);});}function readJsonFile(filename, callback) {readFile(filename, function (err, content) {if (err){ return callback(err); }parseJson(content, callback);});}function writeCsvFile(target, data, callback) {convertToCsv(data, function (err, csv) {if (err) { return callback(err); }writeFile(target, csv, callback);});}



4. 避免加入上下文的变量

如果混入了函数以外的变量,那么在这个函数在别的地方被调用的时候就会出现不可预见的结果
var CACHE = {};
function getRecord(id, callback) {
if (CACHE[id])
{ return CACHE[id]; }
http.get('http://foo/' + id, callback);
}

//别人在用这段代码的时候容易忘记CACHE变量
function getMyRecord(user, callback)
{ getRecord('record-' + user.id, callback); }


5. 总是对err参数编写相应的错误处理函数

忘记处理err变量可以视为是一种bug
//Wrong code:
function writeCsvFile(target, data, callback) {
  convertToCsv(data, function (err, csv)
  { writeFile(target, csv, callback); }
  );
}

//Right code:
function writeCsvFile(target, data, callback) {
  convertToCsv(data, function (err, csv) {
    if (err)
    { return callback(err); }
  writeFile(target, csv, callback);
  });
}


注意 : 记得返回callback函数,以下的写法会造成虽然callback被调用了,但是代码还是继续执行下去了
if (err){ callback(err); }


6. 永远不要使用 with 或者 eval

7. 用 === 代替 ==

8. 声明变量的时候总是带 var

不要污染 global 范围的变量

9. 回调函数总是把err参数作为第一个变量,如果参数中有回调函数,总是放在最后

比如  callback(err, param1, param2, callback)

PS:更详细的 Node.js 代码规范见:

https://github.com/felixge/node-style-guide
http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml
Reference:
http://geoff.greer.fm/2012/06/10/nodejs-dealing-with-errors/
http://stackoverflow.com/questions/5495984/coding-style-guide-for-node-js-apps