node基础知识

Node.js 是一个冲 Chrome V8 引擎的
JavaScript 运行环境,是一个可为 JavaScript 运行于服务器端的阳台

Node.js 以了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。Node.js
的承保管理器 npm,是举世最充分之开源库生态系统。

以了单线程、异步式I/O、事件驱动式的顺序设计模型

I/O(input/output),即输入/输出端口。每个设备还见面发出一个专用的I/O地址,用来拍卖好的输入输出信息。

ctrl + c – 退出时极。

ctrl + c 按部就班下零星不行 – 退出 Node REPL。

ctrl + d – 退出 Node REPL.

向上/向下 键 – 查看输入的史命令

tab  – 列出当前命令

help – 列出利用命令

break – 退出多执表达式

.clear – 退出多尽表达式

save filename – 保存时之 Node REPL 会话到指定文件

load filename – 载入当前 Node REPL 会话的文书内容。

 

Node.js 事件循环

Node.js
是特进程单线程应用程序,但是通过波和回调支持并发,所以性能特别高。

Node.js 的每一个 API
都是异步的,并作为一个独立线程运行,使用异步函数调用,并处理并发。

Node.js 基本上有的波机制都是为此设计模式中观察者模式实现。

Node.js
单线程类似进入一个while(true)的轩然大波循环,直到没有事件观察者退出,每个异步事件还怪成一个事变观察者,如果产生事件产生就调用该回调函数.

 

观察者模式:观察者模式定义了一样栽同等对准几近之靠关系,让大多独观察者对象又监听某一个主题对象。这个主题对象在状态发生变化时,会打招呼所有观察者对象,使她能够自动更新自己。

 

事件驱动程序

Node.js 以事件驱动模型,当web
server接收到请求,就将她倒闭然后开展处理,然后去服务下一个web请求。

当此要完成,它被放回处理队列,当到队列开头,这个结果被归给用户。

夫模型非常迅猛而扩展性非常强,因为webserver一直接受请求而未待其他读写操作。(这也深受称之为非阻塞式IO或者事件驱动IO)

于事件驱动模型中,会转变一个主循环来监听事件,当检测及事件时触发回调函数。

 

 

总体事件驱动的流水线就是如此实现的,非常简洁。有点类似于观察者模式,事件相当给一个主题(Subject),而持有注册到之事件及之处理函数相当给观察者(Observer)。

Node.js 有差不多独放的波,我们可由此引入 events 模块,并通过实例化
EventEmitter 类来绑定和监听事件

 

 

Node.js 中所谓的 JavaScript 只是 Core JavaScript,或者说是 ECMAScript
的一个实现,不含 DOM(文档对象模型)、BOM(浏览器对象模型) 或者
Client JavaScript(客户端脚本)。这是坐 Node.js
不运行于浏览器被,所以不需要使用浏览器中之无数特点。

 

Node.js 能开呀

怀有复杂性逻辑的网站;

冲社交网络的广 Web 应用;

Web Socket 服务器;

TCP/UDP 套接字应用程序;

命令行工具;

交互式终端程序;

含图形用户界面的本土应用程序;

单元测试工具;

客户端 JavaScript 编译器。

 

TCP/UDP协议

TCP (Transmission Control Protocol)和UDP(User Datagram
Protocol)协议属于传输层情商。其中TCP提供IP环境下之数额保险传输,它提供的劳务包括数据流传送、可靠性、有效流控、全双工操作和多路复用。通过面向连接、端到端与可靠的数据包出殡。通俗说,它是优先呢所发送的数量开辟有连接好之康庄大道,然后又展开数据发送;而UDP则非呢IP提供可靠性、流控或差错恢复功能。一般的话,TCP对应的是可靠性要求大的施用,而UDP对应的尽管是可靠性要求低、传输经济的行使。TCP支持的行使协议主要发生:Telnet、FTP、SMTP等;UDP支持的应用层协和要出:NFS(纱文件系统)、SNMP(简单网络管理协议)、DNS(主域名称系统)、TFTP(通用文件传输协议)等。

 

Node.js 用异步式 I/O 和事件驱动代替多线程,带来了高度之性提升。Node.js
除了运用 V8 作为JavaScript引擎以外,还使了便捷之 libev 和 libeio
库支持事件驱动和异步式 I/O。

 

 

 

CommonJS 为了统一javascript在浏览器外之贯彻

CommonJS
规范包括了模块(modules)、包(packages)、系统(system)、二进制(binary)、控制台(console)、编码(encodings)、文件系统(filesystems)、套接字(sockets)、单元测试(unit
testing)等一些。目前大部分业内还当拟和议论其中,已经揭晓之正规化发

Modules/1.0、Modules/1.1、Modules/1.1.1、Packages/1.0、System/1.0。

 

REPL (Read-eval-print loop),即输入—求值—输出循环

例子:

$ node

> console.log(‘Hello World’);

Hello World

Undefined

 

Supervisor工具

当开发 Node.js 实现之 HTTP
应用时会发觉,无论你改改了代码的啦一样总统份,都要下马

Node.js 重新重复运行才见面立竿见影。这是盖 Node.js
只有在首先蹩脚引用到有份时才会错过分析脚本文件,以后还见面直接看内存,避免重复载入,

Node.js的这种设计则有益于增进性,却非便利开发调试,因

为我们当出进程被接二连三想改后立即看到效果,而不是历次都要停进程并再度开。

supervisor 可以拉而实现者作用,它见面监视你对代码的变动,并活动还启
Node.js。

应用方式好粗略,首先利用 npm 安装 supervisor:

$ npm install -g supervisor

比方你以的是 Linux 或
Mac,直接键入上面的下令很可能会见时有发生权力错误。原因是 npm需要把 supervisor
安装至系统目录,需要管理员授权,可以以  sudo npm install -gsupervisor
命令来设置。

接通下去,使用 supervisor 命令启动 app.js:

$ supervisor app.js

 

异步式 I/O 与事件式编程

Node.js 最可怜之特色就是异步式 I/O(或者非阻塞
I/O)与事件紧密结合的编程模式。这种模式与习俗的同步式 I/O
线性的编程思路有非常十分之不同,因为控制流动很充分程度达到如乘事件与回调函数来组织,一个逻辑要拆分为几独单元。

卡住与线程

哎呀是死(block)呢?线程在实行着假如赶上磁盘读写或网络通信(统称为
I/O 操作),通常如吃较丰富之光阴,这时操作系统会剥夺这个线程的 CPU
控制权,使该暂停实施,同时用资源让其他的干活线程,这种线程调度方式叫
阻塞。当 I/O
操作结束时,操作系统将这线程的阻塞状态解除,恢复该针对性CPU的控制权,令其继续执行。这种
I/O 模式就是是通常的同步式 I/O(Synchronous I/O)或阻塞式 I/O (Blocking
I/O)。

对应地,异步式 I/O (Asynchronous I/O)或非阻塞式 I/O (Non-blocking
I/O)则对具有 I/O 操作不以阻塞的政策。当线程遇到 I/O
操作时,不会见因死的方等 I/O 操作的落成或者数额的归,而独自是将 I/O
请求发送给操作系统,继续执行下一样长条语句。当操作系统完成 I/O
操作时,以事件的花样通知执行 I/O
操作的线程,线程会以特定时刻处理者事件。为了处理异步
I/O,线程必须有事件循环,不断地反省出无发未处理的风波,依次给拍卖。

闭塞模式下,一个线程只能处理同宗职责,要惦记增强吞吐量必须透过多线程。而休死模式下,一个线程永远在实施计算操作,这个线程所利用的
CPU 核心利用率永远是 100%,I/O
以事件之点子通知。在堵塞模式下,多线程往往能够增强系统吞吐量,因为一个线程阻塞时还出其它线程在劳作,多线程可以于
CPU 资源不给卡住中的线程浪费。而当非阻塞模式下,线程不会见受 I/O
阻塞,永远在采用 CPU。多线程带来的补益就是于差不多核 CPU
的情形下以再次多的对,而Node.js的单线程也克带动同样的利。这便是为什么
Node.js 使用了单线程、非阻塞的波编程模式

 

单线程事件驱动的异步式 I/O 比传统的多线程阻塞式 I/O
究竟好以乌啊?简而言之,异步式 I/O
就是少了多线程的开销。对操作系统来说,创建一个线程的代价是十分贵之,需要为它们分配内存、列入调度,同时在线程切换的下还要实行外存换页,CPU
的休养生息存给清空,切换回来的时候还要还于外存中读取信息,破坏了数码的区域性。

 

 

掉调函数

Node.js 中争用异步的主意读取一个文书

//readfile.js

var fs = require(‘fs’);

fs.readFile(‘file.txt’, ‘utf-8’, function(err, data) {

if (err) {

console.error(err);

} else {

console.log(data);

}

});

console.log(‘end.’);

运作的结果如下:

end.

Contents of the file.

 

注:function()是回调函数,在Node.js 中,异步式 I/O
是由此回调函数来实现的。 fs.readFile 
接收了三只参数,第一独凡是文件称,第二独是编码方式,第三个是一个函数,我们遂之函数为回调函数。

JavaScript
支持匿名的函数定义方式,譬如我们例子中回调函数的定义就是是嵌套在fs.readFile 
的参数表中的。这种概念方式以 JavaScript 程序中多广阔,与下部这种概念

措施实现之功效是同的:

//readfilecallback.js

function readFileCallBack(err, data) {

if (err) {

console.error(err);

} else {

console.log(data);

}

}

var fs = require(‘fs’);

fs.readFile(‘file.txt’, ‘utf-8’, readFileCallBack);

console.log(‘end.’);

fs.readFile  调用时所召开的办事只是用异步式 I/O
请求发送给了操作系统,然后就回到并实行后的语,执行完毕以后进入事件循环监听事件。当
fs  接收至 I/O
请求完成的波频仍,事件循环会主动调用回调函数以好后续工作。因此我们见面优先看
end. ,再看看file.txt 文件之情节

 

事件

Node.js 所有的异步 I/O
操作以完成时犹见面发送一个轩然大波及事件队列。在开发者看来,事件由
EventEmitter  对象提供。

 

Node.js 的轩然大波循环机制

Node.js 于什么时会进来事件循环呢?答案是 Node.js
程序由事件循环开始,到事件循环结束,所有的逻辑都是事件的回调函数,所以
Node.js
始终以波循环中,程序入口即是事件循环第一单事件之回调函数。事件之回调函数在履行的进程遭到,可能会见时有发生
I/O
请求或直接发射(emit)事件,执行完毕后再行回事件循环,事件循环会检查事件队列中出没起不处理的波,直到程序结束。

 

 

模块和保管

好家伙是模块

模块是 Node.js
应用程序的骨干有,文件和模块是逐一对应的。换言之,一个Node.js
文件就是一个模块,这个文件或者是 JavaScript 代码、JSON 或者编译过的
C/C++ 扩展。

 

以前头章节的例证中,我们曾采用了  var http = require(‘http’), 其中
http是 Node.js 的一个着力模块,其里面是为此 C++ 实现之,外部用 JavaScript
封装。我们通过require 函数获取了是模块,然后才会采取中的靶子。

 

创建与加载模块

1. 创办模块

一个文书就是一个模块

Node.js 提供了 exports 和  require  两个对象,其中  exports
是模块公开之接口, require 用于从外表得到一个模块的接口,即所获取模块的 
exports 对象。

 

例子:

//module.js

var name;

exports.setName = function(thyName) {

name = thyName;

};

exports.sayHello = function() {

console.log(‘Hello ‘ + name);

};

 

在同等目录下创办 getmodule.js,内容是:

//getmodule.js

var myModule = require(‘./module’);

myModule.setName(‘BYVoid’);

myModule.sayHello();

运行node getmodule.js,结果是:

Hello BYVoid

 

每当以上示例中,module.js 通过  exports 对象将 setName  和  sayHello
作为模块的拜访接口,在 getmodule.js 中通过  require(‘./module’)
加载这个模块,然后就得一直访问 module.js 中  exports
对象的积极分子函数了。

 

2. 单次加载

上面这例子有接触类似于创造一个对象,但其实和对象又产生精神之区别,因为

require 不会见更加载模块,也就是说无论调用多少坏  require,
获得的模块都是与一个。

俺们当 getmodule.js 的根底及小作改:

//loadmodule.js

var hello1 = require(‘./module’);

hello1.setName(‘BYVoid’);

var hello2 = require(‘./module’);

hello2.setName(‘BYVoid 2’);

hello1.sayHello();

运转后发觉输出结果是  Hello BYVoid 2 ,这是以变量  hello1 和hello2
指向的是跟一个实例,因此  hello1.setName 的结果让 hello2.setName
覆盖,最终输出结果是由后者决定的。

 

3. 覆盖  exports

管一个对象封装到模块中,例如:

//singleobject.js

function Hello() {

var name;

this.setName = function (thyName) {

name = thyName;

};

this.sayHello = function () {

console.log(‘Hello ‘ + name);

};

};

exports.Hello = Hello;

这会儿咱们于其它文件被需要通过 require(‘./singleobject’).Hello 
来取得Hello  对象,这小发冗余,可以用底方法稍微简化:

//hello.js

 

function Hello() {

var name;

this.setName = function (thyName) {

name = thyName;

};

this.sayHello = function () {

console.log(‘Hello ‘ + name);

};

};

module.exports = Hello;

//gethello.js

var Hello = require(‘./hello’);

hello = new Hello();

hello.setName(‘BYVoid’);

hello.sayHello()

 

留意,模块接口的唯一变化是采用  module.exports = Hello 代替了 
exports.Hello=Hello 。在表面引用该模块时,其接口对象就是设出口的  Hello
对象自我,而休是原先的exports 。

其实, exports  本身只是是一个通常的空对象,即 {}
,它特别就此来声称接口,本质上是由此其吗模块闭包的中建立了一个个别的顾接口。因为它没有任何特殊之地方,所以可以为此任何东西来代表,譬如我们地方例子中的
Hello  对象。

 

警告:

莫得以经对exports 直接赋值代替对module.exports 赋值。

exports 实际上只是一个跟  module.exports
指于与一个靶的变量,它本身会当模块执行了晚刑满释放,但
module不会,因此只能通过点名module.exports 来改访问接口。

 

创建包

包是在模块基础及再也特别一步之悬空,Node.js 的包类似于 C/C++ 的函数库或者
Java/.Net的类库。它将有独立的效力封装起来,用于发布、更新、依赖管理及版本控制。Node.js
根据 CommonJS 规范落实了保证机制,开发了 npm来解决确保之揭晓以及取需求。

Node.js 的保管是一个目录,其中包含一个 JSON 格式的管教说明文件
package.json。严格符合 CommonJS 规范的保险应该具备以下特点:

package.json 必须于担保的顶层目录下;

  二进制文件应该在 bin 目录下;

  JavaScript 代码应该于 lib 目录下;

  文档应该当 doc 目录下;

  单元测试应该在 test 目录下。

1. 当文件夹的模块

模块和公事是各个对应的。文件不但可以是 JavaScript
代码或二前进制代码,还可是一个文书夹。最简单易行的承保,就是一个看成文件夹的模块

例子:

立一个叫做 somepackage  的文本夹,在其间创建 index.js,内容如下:

//somepackage/index.js

exports.hello = function() {

console.log(‘Hello.’);

};

下一场于  somepackage 之外建立 getpackage.js,内容如下:

//getpackage.js

var somePackage = require(‘./somepackage’);

somePackage.hello();

运作 node getpackage.js,控制台将出口结果 Hello. 。

咱俩采取这种方法可以将公文夹封装为一个模块,即所谓的保险。包通常是一些模块的成团,在模块的根基及提供了双重高层的架空,相当给提供了有恒定接口的函数库。通过定制

package.json,我们好创造更扑朔迷离、更宏观、更符合规范的保管用于发布。

  1. 2.       package.json

在面前例子中的 somepackage 文件夹下,我们创建一个称作 package.json
的文本,内容而

下所示:

{

“main” : “./lib/interface.js”

}

然后将 index.js 重命名吧 interface.js 并放入 lib
子文件夹下。以同的法子更调用这个保险,依然可正常使用。

Node.js 于调用某个包时,会率先检查包中 package.json 文件的 main 
字段,将其当担保之接口模块,如果 package.json 或 main
字段未存,会尝试摸 index.js 或 index.node 作为确保之接口。

 

备考:package.json里面未可知出main{}之类的注释,不然会报错

 

package.json是CommonJS 规定的用来描述包之公文,完全符合规范之
package.json 文件应当包含以下字段。

name
:包之称谓,必须是唯一的,由小写英文字母、数字与下划线组成,不克包含空格。

description :包之简练说明。

version :符合语义化版本识别

keywords :关键字数组,通常用于搜索。

maintainers :维护者数组,每个元素而包含 name 、 email (可选)、 web
(可选)字段。

contributors :贡献者数组,格式和 maintainers
相同。包之撰稿人应是贡献者数组的首先独因素。

bugs :提交bug的地方,可以是网址或者电子邮件地址。

licenses :许可证数组,每个元素而含有 type (许可证之称谓)和  url
(链接到许可证文本的地点)字段。

repositories :仓库托管地址数组,每个元素如包含 type  (仓库的门类,如 
git )、url (仓库的地方)和  path (相对于仓库的路,可摘)字段。

dependencies :包的凭,一个涉嫌数组,由保险号及版本号组成。

 

例子:

{

“name”: “mypackage”,

“description”: “Sample package for CommonJS. This package demonstrates
the required

elements of a CommonJS package.”,

“version”: “0.7.0”,

“keywords”: [

“package”,

“example”

],

“maintainers”: [

{

“name”: “Bill Smith”,

“email”: “bills@example.com”,

}

],

“contributors”: [

{

“name”: “BYVoid”,

“web”: “http://www.byvoid.com/”

}

],

“bugs”: {

“mail”: “dev@example.com”,

“web”: “http://www.example.com/bugs”

},

“licenses”: [

{

“type”: “GPLv2”,

“url”: “http://www.example.org/licenses/gpl.html”

}

],

“repositories”: [

{

“type”: “git”,

“url”: “http://github.com/BYVoid/mypackage.git”

}

],

“dependencies”: {

“webkit”: “1.2”,

“ssl”: {

“gnutls”: [“1.0”, “2.0”],

“openssl”: “0.9.8”

}

}

}

 

Node.js 保证管理器

Node.js包管理器,即npm是 Node.js 官方提供的保证管理工具,它已经成了
Node.js 包的科班通告平台,用于 Node.js 包的揭示、传播、依赖控制。npm
提供了命令行工具,使您可以便宜地下载、安装、升级、删除包,也堪让您作开发者发布并维护包。

 

本地模式和大局模式

本土模式:npm [install/i] [package_name]

全局模式:npm [install/i]  -g  [package_name]

 

怎要用全局模式呢?多数时段并无是以众多次还发出或因此到她,为了减少多又称本而以全局模式,而是因为地方模式不会见报 
PATH 环境变量。举例说明,我们设置supervisor
是为在指令行中运行它们,譬如直接运行 supervisor script.js,这时便需要以 
PATH环境变量中登记 supervisor。npm 本地模式仅仅是管包安装至
node_modules 子目录下,其中的 bin 目录没有包含在 PATH 
环境变量中,不可知直接在指令行中调用。而当我们用全局模式安装时,npm
会将确保安装到系统目录,譬如 /usr/local/lib/node_modules/,同时
package.json 文件中 bin 字段包含的文本会让链接到
/usr/local/bin/。/usr/local/bin/ 是以 PATH
环境变量中默认定义的,因此即便足以直接在指令行中运行 supervisor script.js
命令了。

 

 

 

创全局链接

npm 提供了一个有意思的指令 npm
link,它的功力是以地方包和全局包里面创造符号链接。我们说过用全局模式安装的担保不克一直通过require
使用,但经  npm link 命令可以打破这同限。举个例子,我们既经过  npm
install -g express 安装了  express ,这时在工程的目下运作命令:

$ npm link express

./node_modules/express -> /usr/local/lib/node_modules/express

咱们得在 node_modules
子目录中发觉一个对安装至全局的担保之号链接。通过这种办法,我们即便足以把全局包当本地包来使用了。

 

保证的昭示

*编模块

1)新建文件夹,比如:somepackage

2) 该公文夹下新建js文件,比如:index.js

  js内容如下:

  exports.sayHello=function(){
    return “Hello,zhoudaozhang.”;
  };

 

*初始化包描述文件

运用cmd命令定位及somepackage文件夹

输入 npm init 并执行

npm的init命令可以辅助你生成package.json文件,这是我之公文内容:

{
“name”: “somepackage_xiaotian”,
“version”: “1.0.0”,
“description”: “‘hehe'”,
“main”: “index.js”,
“scripts”: {
“test”: “echo \”Error: no test specified\” && exit 1″
},
“keywords”: [
“Hello”,
“world”
],
“author”: “zhou daozhang”,
“license”: “ISC”
}

 

*登记包仓库账号

npm adduser

输入是令会来提醒输入用户称,密码,邮箱等材料

马上和失去官方源仓库https://www.npmjs.com/注册是一样的

 

*上传包

npm publish

万一达污染成会晤提醒

+somepackage_xiaotian@1.0.0 否则上污染失败

其一时去https://www.npmjs.com/登陆仓库账号就可以看到自己的包啦

 

*安装包

npm install somepackage_xiaotian

经过之命令可以在世界上任一一玉机械及安somepackage_xiaotian了

 

宣布包过程或者会见遇到不少题目,我印象比较浓厚的凡npm ERR publish 403

You do not have permission to publish ‘somepackage’.Are you logged in as

the corrent user?:somepackage

意思是本身并未权力发布somepackage,并咨询我是否用了不易的账号,

那可能是somepackage被人家宣布了了吧,所以我修改了package.json文件

把name改成somepackage_xiaotian.

 

*分析包

此令可以吗你分析产生脚下路线下能透过模块路径找到的具有保险,并转移依赖树。

npm ls

 

 

大局对象Global

JavaScript 中发生一个非常之目标,称为全局对象(Global
Object),它及其所有属性都得以程序的任何地方看,即全局变量。在浏览器
JavaScript 中,通常 window  是大局对象,而 Node.js 中的全局对象是 
global ,所有全局变量(除了 global 本身以外)都是  global

靶的属性。

 

大局对象和全局变量

global 最根本之企图是当全局变量的宿主

满足以下规则的变量是全局变量:

在太外层定义的变量;

  全局对象的性能;

  隐式定义之变量(未定义直接赋值的变量)。

流动:在 Node.js
中而无容许于最为外层定义变量,因为所有用户代码都是属于即模块的,而模块本身不是最外层上下文

提拔:永远以 var 
定义变量以避免引入全局变量,因为全局变量会传染命名空间,提高代码的耦合风险。

 

Process

process  是一个全局变量,即  global 对象的特性。它用来描述当前 Node.js
进程状态的目标,提供了一个和操作系统的略接口

 

process.argv 是命令执行参数数组,第一只要素是 node,第二独元素是本子文件称

process.stdout 是标准输出流,通常咱们以的  console.log()
向专业输出打印字符,而  process.stdout.write() 函数提供了再底层的接口。

process.stdin
是正式输入流,初始时它们是让暂停的,要惦记从正规输入读取数据,你必须恢复流,并手动编写流的波响应函数。

process.nextTick(callback) 的效果是也事件循环设置同一件职责,Node.js
会在下次事件循环调响应时调用  callback 。

 

http://nodejs.org/api/process.html翔摸底的地方

 

console

console  用于供控制高标准输出

console.log() :向专业输出流打印字符并盖变换行符结束

console.error() :与 console.log() 用法平,只是于专业错误流输出。

console.trace() :向专业错误流输出当前之调用栈。

 

常用工具  util

util  是一个 Node.js 核心模块,提供常用函数的集纳,用于弥补中心
JavaScript 的力量过于简单的贫乏。

 

util.inherits

util.inherits(constructor, superConstructor)
是一个落实目标中原型继承的函数。

var util = require(‘util’);

function Base() {

this.name = ‘base’;

this.base = 1991;

this.sayHello = function() {

console.log(‘Hello ‘ + this.name);

};

}

Base.prototype.showName = function() {

console.log(this.name);

};

function Sub() {

this.name = ‘sub’;

}

util.inherits(Sub, Base);

var objBase = new Base();

objBase.showName();

objBase.sayHello();

console.log(objBase);

var objSub = new Sub();

objSub.showName();

//objSub.sayHello();

console.log(objSub);

 

结果:

base

Hello base

{ name: ‘base’, base: 1991, sayHello: [Function] }

sub

{ name: ‘sub’ }

 

此只能继续原型里面的属性与法

 

util.inspect

 

util.inspect(object,[showHidden],[depth],[colors])
是一个拿轻易对象转换为字符串的措施,通常用于调试以及不当输出。它起码接受一个参数 
object ,即如果更换的目标。

showHidden  是一个可选参数,如果值为  true ,将会见输出更多隐蔽信息。

depth 
代表最好充分递归的层数,如果目标好复杂,你可指定层数以控制输出信息之大都

掉。如果未指定 depth ,默认会递归2层,指定为  null 
表示以不限递归层数完整遍历对象。

假如 color 值为  true ,输出格式将会晤坐 ANSI
颜色编码,通常用于在终极显示更美好的效力。

 

注:util.inspect  并无会见略地一直将目标转换为字符串,即使该对

象定义了 toString  方法呢非会见调用。

 

 

module.exports 和exports的区别?

Module.exports才是的确的接口,exports只不过是它的一个辅助工具。 最终回给调用的是Module.exports而不是exports。

所有的exports采集至的性能和法,都赋值给了Module.exports。当然,这发生个前提,就是Module.exports本人不持有任何性质和办法。如果,Module.exports已经有一些特性和方,那么exports收集来之音讯用吃忽略。

 

立就是 EventEmitter 最简单易行的用法。接下来我们介绍一下 EventEmitter
常用的API。

  EventEmitter.on(event, listener) 
为指定事件注册一个监听器,接受一个字符串  event  和一个回调函数 
listener 。

  EventEmitter.emit(event, [arg1], [arg2], […]) 发射  event 
事件,传递若干但选参数到事件监听器的参数表。

  EventEmitter.once(event, listener) 
为指定事件注册一个单次监听器,即监听器最多才见面沾一不好,触发后及时解除该监听器。

  EventEmitter.removeListener(event, listener)
移除指定事件之某监听器, listener  必须是拖欠事件早已报了之监听器。

 

 

文件系统  fs

fs
模块是文本操作的包裹,它提供了文本之读取、写副、更叫、删除、遍历目录、链接等
POSIX 文件系统操作。与外模块不同之是, fs
模块中具备的操作都提供了异步的跟共的有限只本子,例如读取文件内容的函数有异步的 
fs.readFile() 和旅的fs.readFileSync() 。

 

fs.readFile

fs.readFile(filename,[encoding],[callback(err,data)]) 是最最简便的读取

文本的函数。它接受一个必选参数  filename
,表示若读取的公文称。第二单参数  encoding是可选的,表示文件之字符编码。
callback 是回调函数,用于收纳文件的情。如果未指定  encoding ,则 
callback 就是第二单参数。回调函数提供个别单参数  err 和  data , err
代表来没有起误产生, data 是文件内容。如果指定了  encoding , data
是一个剖析后的字符串,否则  data 将会见是盖  Buffer 形式表示的二进制数据。

 

例;

 

因  Buffer 形式表示的二进制数据

var fs = require(‘fs’);

fs.readFile(‘content.txt’, function(err, data) {

if (err) {

console.error(err);

} else {

console.log(data);

}

});

 

encoding 指定编码

var fs = require(‘fs’);

fs.readFile(‘content.txt’, ‘utf-8’, function(err, data) {

if (err) {

console.error(err);

} else {

console.log(data);

}

});

 

fs.readFileSync

fs.readFileSync(filename, [encoding]) 是  fs.readFile
同步的版。它承受之参数和  fs.readFile
相同,而读博到之文书内容会因函数返回值的款式返回。如果出误产生, fs
将会晤扔来怪,你需要使用  try 和  catch 捕捉并处理好。

 

Fs.read

fs.read(fd, buffer, offset, length, position, [callback(err, bytesRead,

buffer)]) 是 POSIX  read 函数的包,相比fs.readFile
提供了又底层的接口。 fs.read的成效是由指定的文本讲述符fd
中读取数据并勾画副  buffer 指向的缓冲区对象。offset 是buffer
的刻画副偏移量。length 是要自文本中读取的字节数。position 是文件读取的苗子

职,如果  position 的值也  null
,则会从当下文件指针的职位读取。回调函数传递bytesRead 和  buffer
,分别表示读取的字节数和缓冲区目标。

 

故此的上,和fs.open一起用

 

 

var fs = require(‘fs’);

fs.open(‘content.txt’, ‘r’, function(err, fd) {

if (err) {

console.error(err);

return;

}

var buf = new Buffer(8);

fs.read(fd, buf, 0, 8, null, function(err, bytesRead, buffer) {

if (err) {

console.error(err);

return;

}

console.log(‘bytesRead: ‘ + bytesRead);

console.log(buffer);

})

});

运作结果则是:

bytesRead: 8

<Buffer 54 65 78 74 20 e6 96 87>

 

HTTP 服务器和客户端

 

工的构造

Express 都格外成了如何文件,除了 package.json,它仅发生了片只 JavaScript
文件 app.js 和 routes/index.js。模板引擎 ejs 也发出个别文书 index.ejs
和layout.ejs,此外还有样式表 style.css。下面来详细看看这几只文件。

  1. app.js

routes  是一个文本夹式的本地模块,即 ./routes/index.js
,它的效能是为指定路线组织返回内容,相当给 MVC 架构中之控制器。

  1. routes/index.js

routes/index.js 是里程由于文件,相当给控制器,用于集体展示的情:

exports.index = function(req, res) {

res.render(‘index’, { title: ‘Express’ });

};

app.js 中通过 app.get(‘/’, routes.index); 将“ / ”路径映射到 
exports.index函数下。其中仅来一个谈  res.render(‘index’, { title:
‘Express’ }) ,功能是调用模板解析引擎,翻译名为也 index
的沙盘,并传一个靶作为参数,这个目标只是生一个

属性,即  title: ‘Express’ 。

  1. index.ejs

index.ejs 是模板文件,即 routes/index.js 中调用的模版,内容是:

<h1><%= title %></h1>

<p>Welcome to <%= title %></p>

它们的基本功是 HTML 语言,其中蕴蓄了形如<%= title
%>的标签,功能是显得引用的变量,即  res.render
函数第二独参数传入的靶子的性。

  1. layout.ejs  (新的内部,没有这个)

模板文件不是孤立展示的,默认情况下有所的沙盘都累自
layout.ejs,即<%- body %>

有才是异常的情,其他组成部分是共有的,可以看做是页面框架。

<!DOCTYPE html>

<html>

<head>

<title><%= title %></title>

<link rel=’stylesheet’ href=’/stylesheets/style.css’ />

</head>

<body>

<%- body %>

</body>

</html>

 

REST 作风的路由规则

特色状态转移(Representational State Transfer),它是平等种植基于 HTTP
协议的网络使用的接口风格,充分利用 HTTP 的章程实现统一风格接口的服务。

安然是依没有副作用,即要不会见针对资源来变动,连续走访数所获的结果未深受访问者的震慑。而幂等靠的凡再请求多次以及同样破呼吁的作用是同等的,比如取和创新操作是幂等的,这跟新增不同。删除也是幂等的,即再删除一个资源,和去一不良是如出一辙的。

 

 

当 MVC 架构中,模板引擎包含在劳务器端。

冲 JavaScript 的模版引擎起广大种植实现,我们推荐用 ejs (Embedded
JavaScript),因为她充分简约,而且同 Express 集成良好。由于其是业内
JavaScript 实现之,因此它们不但可运行在服务器端,还足以运行于浏览器中。

 

ejs 的价签系统非常简单,它仅仅发以下3种标签。

  <% code %>:JavaScript 代码。

  <%= code %>:显示替换了 HTML 特殊字符的情节。

  <%- code %>:显示原始 HTML 内容。

 

望图助手

Express
提供了同样栽叫做视图助手的家伙,它的成效是许在视图中走访一个大局的函数或对象,不用每次调用视图解析的时候单独传入。前面提到的
partial 就是一个视图助手。

出于ejs的升迁,《node.js开发指南》中运用的  partial
函数已经丢掉,使用foreach,include代替

<%- partial(‘listitem’,items) %>

修改为:

1

2

3

4

<ul><% items.forEach(function(listitem){%>

    <% include listitem%>

    <%}) %>

</ul>

 

 

next()

Express 提供了行程由于控制权转移的方,即回调函数的老三独参数 next
,通过调用next() ,会以行程由于控制权转移给末端的条条框框,例如:

app.all(‘/user/:username’, function(req, res, next) {

console.log(‘all methods captured’);

next();

});

app.get(‘/user/:username’, function(req, res) {

res.send(‘user: ‘ + req.params.username);

});

当访问于匹配到的途径时,如
http://localhost:3000/user/carbo,会发现终端中打印了  allmethods
captured ,而且浏览器中显得了  user: carbo
。这证明求先让第一久总长由于规则捕获,完成 console.log  使用 next()
转移控制权,又受第二长长的规则捕获,向浏览器返回了消息。

 

随即是一个万分实惠之家伙,可以于咱随便地实现中件,而且还会增高代码的复用程度。例如我们对一个用户查询信息及改信息之操作,分别对应了
GET 和 PUT 操作,而双方共有的一个手续是检查用户名是否合法,因此好经
next()  方法实现:

var users = {

‘byvoid’: {

name: ‘Carbo’,

website: ‘http://www.byvoid.com’

}

};

app.all(‘/user/:username’, function(req, res, next) {

// 检查用户是否是

if (users[req.params.username]) {

next();

} else {

next(new Error(req.params.username + ‘ does not exist.’));

}

});

app.get(‘/user/:username’, function(req, res) {

// 用户定有,直接展示

res.send(JSON.stringify(users[req.params.username]));

});

app.put(‘/user/:username’, function(req, res) {

// 修改用户信息

res.send(‘Done’);

});

方例子中, app.all 
定义之此路程由于规则实际上从至了中间件的意图,把一般请求

的等同部分提取出来,有利于代码维护其他 next
方法要接受了参数,即意味着来了错。

使这种方法可以拿错检查分段化,降低代码耦合度。

 

微博网站过程中窥见的部分问题;

1、          css和javascritp的路径不用写绝对路径,例:

<script src=”/javascripts/jquery-1.11.3.js”></script>
<script src=”/javascripts/bootstrap.js”></script>
<link rel=’stylesheet’ href=’/stylesheets/bootstrap.css’ />
<link href=”/stylesheets/bootstrap-responsive.css”
rel=”stylesheet”>

2、          app.js里面要加是

3、     var partials = require('express-partials');

app.use(partials());

前若安装express-partials模块,npm install express-partials –g

3方是只要写以

app.set('views', path.join(__dirname, 'views'));

app.set('view engine', 'ejs');

后面

 

 

数据库的格式是由表(table)、行(row)、字段(field)组成的。表有固定的布局,规定了

每行有什么样字段,在创建时吃定义,之后修改好艰难。行之格式是同样的,由几独定点的字段组成。每个表或发若干单字段作为目录(index),这中间有些是主键(primary
key),用于约束表中的数目,还有唯一键(unique
key),确保字段中莫存重复数据。表和表之间

恐还有互动的牢笼,称为外键(foreign
key)。对数据库的历次查询都如为实行呢单位,复杂的询问包括嵌套查询、连接查询及交叉表查询。

富有这些力量的数据库被叫做关系项目数据库,关系项目数据库一般用同样种叫做
SQL(Structured Query Language)的询问语言作为接口,因此而称之为 SQL
数据库。典型的 SQL 数据库来 MySQL、Oracle、Microsoft SQL
Server、PostgreSQL、SQLite,等等。

 

 

 

会话

对话是如出一辙栽持久的网络协议,用于完成服务器和客户端里的组成部分互动行为。会话是一个比较连接粒度更要命的定义,一不善对话或含有多次连连,每次连续都叫看是会说话的一律涂鸦操作。在网络使用开发被,有

必要实现会话以帮用户交互。例如网上购物的景象,用户浏览了大多单页面,购买了一些品,这些请求在勤总是着成就。许多应用层网络协议都是由于会话支持的,如
FTP、Telnet 等,而 HTTP
协议是任状态的,本身不支持会话,因此当从来不额外手段之增援下,前面场景被服务器无晓用户买了什么。

以以管状态的 HTTP 协议之上实现会话,Cookie 诞生了。Cookie
是一些囤于客户端的消息,每次连续的时刻由于浏览器为服务器递交,服务器也朝着浏览器发起存储
Cookie 的恳求,依靠这样的手段服务器可以辨别客户端。我们便意义上的 HTTP
会话功能就是这么

实现的。具体来说,浏览器首糟糕为服务器发起呼吁时,服务器生成一个唯一标识符并发送给客户端浏览器,浏览器将是唯一标识符存储在
Cookie
中,以后每次重复发起呼吁,客户端浏览器还见面朝服务器传送这个唯一标识符,服务器通过此唯一标识符来识别用户。

 

Underscore模块