阅读更多

1顶
0踩

编程语言

转载新闻 Node.js 最佳编程实践

2015-07-29 14:40 by 副主编 mengyidan1988 评论(2) 有5804人浏览
本文谈一谈Node.js的最佳实践,包括Node.js的代码风格以及开发者工作流。

代码风格

回调约定
模块应该暴露错误优先的回调接口。
module.exports = function (dragonName, callback) {  
  // do some stuff here
  var dragon = createDragon(dragonName);

  // note, that the first parameter is the error
  // which is null here
  // but if an error occurs, then a new Error
  // should be passed here
  return callback(null, dragon);
}

总是在回调中检查错误: 为了理解这一点,我们从一个违反该规则的例子看起
// this example is **BROKEN**, we will fix it soon :)
var fs = require('fs');

function readJSON(filePath, callback) {  
  fs.readFile(filePath, function(err, data) {  
    callback(JSON.parse(data));
  });
}

readJSON('./package.json', function (err, pkg) { ... }

readJSON函数的最主要的问题是,如果在执行过程中发生Error,它并不会检查这个错误。
改进版本如下:
// this example is **STILL BROKEN**, we are fixing it!
function readJSON(filePath, callback) {  
  fs.readFile(filePath, function(err, data) {
    // here we check, if an error happened
    if (err) {
      // yep, pass the error to the callback
      // remember: error-first callbacks
      callback(err);
    }

    // no error, pass a null and the JSON
    callback(null, JSON.parse(data));
  });
} **在回调中返回!**

上面代码仍然存在的问题是,当Error发生的时候,程序的执行并不会在if语句中停止,而是会继续。这回导致很多意料之外的问题。正如上面加粗部分提到的,总是在回调中返回!
// this example is **STILL BROKEN**, we are fixing it!
function readJSON(filePath, callback) {  
  fs.readFile(filePath, function(err, data) {
    if (err) {
      return callback(err);
    }

    return callback(null, JSON.parse(data));
  });
} **只在同步代码中使用try-catch**

有一点需要注意的是,JSON.parse在无法将指定的字符串格式化为JSON格式的时候会抛出一个异常。

因为JSON.parse是一个同步函数,因此我们可以将其包围在try-catch语句块中。一定要注意的是,只有同步代码块才能使用try-catch,你不能用在回调中!
// this example **WORKS**! :)
function readJSON(filePath, callback) {  
  fs.readFile(filePath, function(err, data) {
    var parsedJson;

    // Handle error
    if (err) {
       return callback(err);
    }

    // Parse JSON
    try {
      parsedJson = JSON.parse(data);
    } catch (exception) {
      return callback(exception);
    }

    // Everything is ok
    return callback(null, parsedJson);
  });
}

避免this和new

在Node中与指定的上下文绑定并不是总是个好事,因为在Node程序中经常涉及到传递回调函数,并且会经常使用高层函数管理工作流。函数风格的编程方式会帮你避免很多麻烦。

创建小模块

使用Unix的方式:
引用

Developers should build a program out of simple parts connected by well defined interfaces, so problems are local, and parts of the program can be replaced in future versions to support new features.

保持模块足够小(内聚),模块应该只做一件事!

使用好的同步模式

使用async

错误处理

错误主要分为两种:操作错误(operational errors)和程序员错误。
Operational errors

例如:
  • 请求超时
  • 系统内存不足
  • 连接远程服务失败

处理Operational errors

Log everything! 启用日志服务!
程序员错误

程序员错误即是程序的bug。这是你可以尽量避免的,比如:
  • 调用异步方法时没有使用回调
  • 无法读取undefined的属性

工作流建议
使用npm init启动一个新项目

init命令帮你创建一个应用的package.json文件,并且会设置一些初始值,便于你后期进行修改。试着用这个命令启动一个新项目吧:
mkdir my-awesome-new-project  
cd my-awesome-new-project  
npm init


指定一个start和test脚本

在package.json中你可以使用script属性设置脚本。默认情况下,npm init会生成两个,start和test。你可以使用npm start和npm test执行他们。

当然你也可以定义自己的脚本,使用如下命令执行npm run-script <SCRIPT_NAME>。

注意,NPM会设置$PATH来查找node_modules/.bin中的可执行文件。这可以避免安装全局的NPM模块。也就是说,例如grunt这样的工具,你可以只安装在项目中,而不是全局安装这个NPM模块。

环境变量

在生产和开发环境可能需要设置不同的环境变量,最通常的方法是通过NODE_ENV来分别设置production或staging。

基于不同的环境变量,你可以载入不同的配置信息,例如可以借助nconf模块

当然你也可以利用process.env在你的Node.js应用程序中使用其他的环境变量,也就是你可以在一个对象中包含用户环境。

可以参考Node的对应文档
不要重复发明轮子

首先寻找已有的解决方案。NPM中包括非常丰富的包,所以请最大化的利用这些资源。

使用风格指南

可以参考RisingStack的Node.js风格指南

References
本文翻译自:https://blog.risingstack.com/node-js-best-practices/
译文来自:http://wwsun.me/
1
0
评论 共 2 条 请登录后发表评论
2 楼 windlike 2015-08-05 10:13
题目写的有点大
1 楼 mangguo 2015-07-30 11:12
代码风格这方面的东西很是受益匪浅,thanks最近也是在学nodejs

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • C++调用其它exe执行文件.

    在C++程序中,调用其它exe执行文件.在C++程序中,调用其它exe执行文件.

  • 关于.c .obj .cpp .exe区别

    1. 编辑源代码 代码在.c 和 .h头文件中写好了以后, 从.c 和.h文件编译成.obj文件 命令: cl /c xxx.c --&gt; xxx.obj 2. 编译源文件 代码被编译为二进制文件.obj以后, 打包一些调用的库, 链接成.exe可执行文件 命令: cl xxx.c --&gt; xxx.objandxxx.exe 3. 链接生成应用程序 ...

  • C++ : XML 文件解析(依赖库:TinyXml)

    XML 文件解析步骤与 Demo,推荐三方库 TinyXML

  • c++多文件结构 & 程序编译后出现的文件

    通常一个项目至少划分3个文件;决定一个声明放在源文件还是头文件中的一般原则;外部变量与外部函数;程序编译后会出现的文件——目标程序文件(*.obj)、无编译浏览文件(*.ncb)、工程文件(*.dsp)、工作区文件(*.dsw)、编译信息文件(*.plg)。

  • visual C++ 项目和解决方案的区别

    项目:         项目是构成某个程序的全部组件的容器,该程序可能是控制台程序、基于窗口的程序或某种别的程序。程序通常由一个或多个包含用户代码的源文件,可能还要加上包含其它辅助数据的文件组成。某个项目的所有文件都存储在相应的项目文件夹中,关于该项目的详细信息存储在一个扩展名为.vcproj的xml文件中,该文件同样存储在相应的项目文件夹中。项目文件夹还包括其它文件夹,它们用来存储编译及链接项

  • c++编译 (.obj, .lib, .dll, .exe的关系(附:lib和DLL的区别))

    转载原网址 c++程序在编译后,在目标路径下会生成多个文件: Debug文件夹(*.exe,*.ilk,*.obj,*.pch,*.pdb,*.idb,*,pdb),*.cpp,*.dsp,*.ncb,*.plg *.exe:是生成的可执行文件 *.ilk:当选定渐增型编译连接时,连接器自动生成ILK文件,记录连接信息 *.obj:是目标文件,源程序编译后的产物 *.pch:全称是PreCompiled Header,就是预先编译好的头文件 *.idb:文件保存的信息,使编译器在重新编译的时候只重编译最新

  • .obj, .lib, .dll, .exe的关系(附:lib和DLL的区别)

    lib是和dll对应的。     lib是静态的库文件,dll是动态的库文件。     所谓静态就是link的时候把里面需要的东西抽取出来安排到你的exe文件中,以后运行     你的exe的时候不再需要lib。     所谓动态就是exe运行的时候依赖于dll里面提供的功能,没有这个dll,你的exe无法运     行。         lib,   dll,   exe都算是最终的目标文件,是

  • C/C++ 多文件编程 ——学习笔记

    当所有代码全部编写在同一个文件中时,代码冗杂, 难以分清结构,而多文件编程可以解决这个问题。 主要结构方式及原理classx.hclassx.cppmain.cppvc 6.0运行多文件建立打开 主要结构 Sources main.cpp:主函数,调用功能。 class1.cpp:类函数、函数的实现。 class2.cpp … Headers “class1.h”: 类、函数的声明。 ...

  • 【C++】之多文件编译原理

    在单文件的情况下(只有一个.h和.c/.cpp)我们只需编译该文件即可,例如: $ gcc main.c -o main 但更多的情况下,一个工程需要分开为多个源文件,比如 main.c、a.c、b.c 等,那这种情况下是如何编译的呢?首先要在 main.c 中调用 a.c 中的方法,必须包含 a.h 头文件,有了头文件中的函数声明就确保了 main.c 的函数调用的正确性。好了,现在我们执行编译多文件命令: $ gcc main.c a.c b.c -o main 整个编译结果是这样的:编译器先把源文

  • C/C++项目中.h和.inc文件区别

    原问题:Difference between .h files and .inc files in c C/C++的标准惯例是将class、function的声明信息写在.h文件中。.c文件写class实现、function实现、变量定义等等。然而对于template来说,它既不是class也不是function,而是可以生成一组class或function的东西。编译器(compiler)为了...

  • 结合编译过程,分析C++头文件和源文件的区别

    头文件和源文件的区别 头文件和源文件在本质上没有任何区别。 只不过一般:后缀为 .h 的文件是头文件,内含函数声明、宏定义、结构体定义等内容。后缀为 .c 的文件是源文件,内含函数实现,变量定义等内容。而且是什么后缀也没有关系,只不过编译器会默认对某些后缀的文件采取某些动作。这样分开写成两个文件是一个良好的编程风格。 原文链接:https://blog.csdn.net/qq_30815237/article/details/88948632 ...

  • c文件和c++文件的区别

    在编译文件的时候,c编译器和c++编译器都会对符号名称做些修订,但两者采用的修正方式不同,所以两者生成的目标文件不能链接。c代码生成的是.c文件,而c++代码生成的是.cpp文件。在标准头文件中都有这样的声明:#ifdef __cplusplusextern "c"{#endif#ifdef __cplusplus}#endif假定某个函数的原型为:void foo(int ...

  • linux中常用C/C++一些头文件的作用

    1、  一些头文件的作用::ANSI C。提供断言,assert(表达式):GCC。GTK,GNOME的基础库,提供很多有用的函数,如有数据结构操作函数。使用glib只需要包含:GCC。文件夹操作函数。struct dirent,struct DIR,opendir(),closedir(),readdir(),readdir64()等:ANSI C。字符测试函数。isdigit(),islowe

  • .obj .lib .dll .exe的关系

    转自: http://blog.csdn.net/iamyina/archive/2008/05/04/2378331.aspx  lib是和dll对应的:lib是静态的库文件,dll是动态的库文件。所谓静态就是link的时候把里面需要的东西抽取出来安排到你的exe文件中,以后运行你的exe的时候不再需要lib。所谓动态就是exe运行的时候依赖于dll里面提供的功能,没有这个d

  • c++文件操作大全

    c++文件操作大全 基于C的文件操作   在ANSI C中,对文件的操作分为两种方式,即流式文件操作和I/O文件操作,下面就分别介绍之。 一、流式文件操作 这种方式的文件操作有一个重要的结构FILE,FILE在stdio.h中定义如下: typedef struct {   int level;           /* fill/empty level of buffer */...

  • C++开发时会生成的所有文件类型说明

    .APS:存放二进制资源的中间文件,VC把当前资源文件转换成二进制格式,并存放在APS文件中,以加快资源装载速度。资源辅助文件。 .BMP:位图资源文件。 .BSC:浏览信息文件,由浏览信息维护工具(BSCMAKE)从原始浏览信息文件(.SBR)中生成,BSC文件可以用来在源代码编辑窗口中进行快速定位。用于浏览项目信息的,如果用source brower的话就必须有这个文件。可以在project options里去掉Generate Browse Info File,这样可以加快编译进度。 .C:用C语言编

  • VC++检测可执行程序DLL、EXE等是32位还是64位

    1.首先介绍PE结构    Windows系统下的可执行文件,是基于Microsoft设计的一种新的文件结构,此结构被称之为PE结构。PE的意思是Portable Executable(可移植的执行体),所有Win32执行体都是用PE文件格式,其中包括SYS、DLL、EXE、COM、OCX等。(不管是学习逆向、破解还是安全,了解PE文件格式都是非常必要的。)    PE文件的第一个部分是IMAGE

  • vc编译后生成的文件类型

    1, PCH文件 预编译头文件(一般扩展名为.PCH),是把一个工程中较稳定的代码预先编译好放在一个文件(.PCH)里.这些预先编译好的代码可以是任何的C/C++代码--甚至可以是inline函数,只它们在整个工程中是较为稳定的,即在工程开发过程中不会经常被修改的代码. 为什么需要预编译头文件?一言以蔽之:提高编译速度.一般地,编译器以文件为单位编译,如果修改了一工程中的一个文件则所有文件都要

Global site tag (gtag.js) - Google Analytics