Node.js

作者:烨竹

本文参考:
https://www.w3cschool.cn/nodejs/
https://nodejs.org/dist/latest-v8.x/docs/api/synopsis.html
http://www.runoob.com/nodejs/nodejs-install-setup.html

简介:Node.js是一个Javascript运行环境(runtime)。实际上它是对Google V8引擎进行了封装。V8引 擎执行Javascript的速度非常快,性能非常好。Node.js对一些特殊用例进行了优化,提供了替代的API,使得V8在非浏览器环境下运行得更好

使用Sublime 编译nodeJS

开启Sublime应用程式,接下来,选功能列 Tools/Build System/New Build System…
此时,会出现一个这样的档案 untitled.sublime-build 将内容修改成:

{
"cmd": ["C:/Program Files/nodejs/node.exe", "$file"]
}

并修改储存成NodeJS.sublime-build
测试:写一些js代码,保存,按Ctrl+B查看编译结果

node.js应用组成

1、引入 required 模块:我们可以使用 require 指令来载入 Node.js 模块。
2、创建服务器:服务器可以监听客户端的请求,类似于 Apache 、Nginx 等 HTTP 服务器。
3、接收请求与响应请求 服务器很容易创建,客户端可以使用浏览器或终端发送 HTTP 请求,服务器接收请求后返回响应数据。

//引入required模块
var http = require('http');

http.createServer(function (request, response) {

    // 发送 HTTP 头部 
    // HTTP 状态值: 200 : OK
    // 内容类型: text/plain
    response.writeHead(200, {'Content-Type': 'text/plain'});

    // 发送响应数据 "Hello World"
    response.end('Hello World\n');
}).listen(8888);

// 终端打印如下信息
console.log('Server running at http://127.0.0.1:8888/');
node server.js
Server running at http://127.0.0.1:8888/

模块

Node.js 有三大类的模块(module Types)
Core Modules (原生模块)
Local Modules (自建模块)
Third Party Modules (第三方模块)

Core Modules (原生模块)

载入Core Modules

var module = require(‘module_name’);

载入modules 的注意事项

var log = require('./utility');

nodeJS把整个utility资料夹,当成一个包,所以,它会自动在这个资料夹里去找package定义文件,预设为package.json,之后,再根据定义文件里的关键字main描述的档名,载入档案。所以解决方案为自行定义一个package.json放在此utility资料夹里
./untility/package.json

{
    "name" : "log",
    "main" : "./log.js"
}

本地自动化功能操作:(module_name)

[http](https://nodejs.org/api/http.html):它包含可以用来建立http server的一些类别,方法,及事件。
[url](https://nodejs.org/api/url.html):它包含可以解析url的一些方法。
[querystring](https://nodejs.org/api/querystring.html):它包含可以处理由client端传来querystring的一些方法。
[path](https://nodejs.org/api/path.html):它包含可以处理一些档案或资料夹路径的方法。
[fs](https://nodejs.org/api/fs.html):它包含档案的存取/操作的一些类别,方法及事件。
[util](https://nodejs.org/api/util.html):它包含一些可供程序者使用的效能函式。

自建模块

log.js(新建)

var log = {
            info: function (info) {
                console.log('Info: ' + info);
            },
            warning:function (warning) {
                console.log('Warning: ' + warning);
            },
            error:function (error) {
                console.log('Error: ' + error);
            }
    };
 
module.exports = log  //這一部很重要,只要,模組(程式)要給別的模組(程式)使用,必須加這個!!

LogApp.js(使用)

var myLogModule = require('./Log.js');
myLogModule.info('Node.js started');

结果:

详解:Exports 物件(exports是一個物件,所以,我们可以直接分派 屬性,函式(方法)及物件给它)
属性

exports.SimpleMessage = 'Hello world';
 
//or
 
module.exports.SimpleMessage = 'Hello world';

使用函式

module.exports.log = function (msg) {
    console.log(msg);
};

使用物件

module.exports = {
    firstName: 'James',
    lastName: 'Bond'
}

Exports 函式(直接分派一个匿名函式给exports)

module.exports = function (msg) {
    console.log(msg);
};

Exports 类别化函式

module.exports = function (firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.fullName = function () {
        return this.firstName + ' ' + this.lastName;
    }
}

NMP管理

简单介绍
npm -v
npm install npm -g //更新nmp
npm help
区域安装(你可以在你的应用文件夹里,安装你想要的套件,)语法

 npm install  <package name>  //注意这里要cd到要安装的文件夹

举例说明如下

C:\cs> npm install express 

生成两个软件

当然,里头也包含了你所安装的express.js模组也在express资料夹内

全域安装语法

 npm install -g express 

更新套件

npm update  <package name>

解除安装套件

npm uninstall   <package name>

更多npm资讯
https://docs.npmjs.com/

Web Server

处理Http Request

http.createServer() 方法,包含Node.js 提供的request 及respones 二个参数。
request 物件可以用来得到一些从http server 发过来的请求,例如url、http header 及data。
response 物件则送出回应给Http 送来的请求
建立

// var http = require('http'); // 1 - 载入 Node.js 原生模组 http
 
// var server = http.createServer(function (request, response) {   // 2 - 建立server
 
//     // 在此处理 客戶端向 http server 发送过來的 req。
 
// });
 
// server.listen(5000); //3 - 进入此网站的监听 port, 就是 localhost:xxxx 的 xxxx
 
// console.log('Node.js web server at port 5000 is running..')
// 
var http=require('http');
var server=http.createServer(function(req,res){
        if(req.url=='/'){
            res.writeHead(200,{'Content-Type':'text/html'});
            res.write('<html><body>This is Home Page.</body></html>');
            res.end();
        }else if(req.url=='/student'){
            res.writeHead(200,{'Content-Type':'text/html'});
            res.write('<html><body>This is student Page.</body></html>');
            res.end();
        }else if(req.url=='/admin'){
            res.writeHead(200,{'Content-Type':'text/html'});
            res.write('<html><body>This is admin Page.</body></html>');
            res.end();
        }else
            res.end('Invalid Request!');
 
});
 
server.listen(5000);

返回json

var http = require('http'); 
 
var server = http.createServer(function (req, res) {   
 
    if (req.url == '/') { //check the URL of the current request
            res.writeHead(200, { 'Content-Type': 'application/json' });
            res.write(JSON.stringify({ message: "Hello World"}));
            res.end();
    }
});
 
server.listen(5000);
 
console.log('Node.js web server at port 5000 is running..')

文件操作

Node.js的fs module ,是用来操作实体档案,可以同步或非同步存取档案系统操作。一般建议使用非同步存取档案,性能高、速度快、无阻塞

非同步读取档案语法

fs.readFile(fileName [,options], callback)
fileName: 档案的完整路径及档名,格式字串。
options: options 可能是一个物件或字串,包含"编码"及"flag"。这里预设的编码是utf8 , flag是"r"。
call back: 是带两个参数的function,err及file data,当我们执行readFile完成时, 要做的事, 例如: 回传file data

例子:

var fs = require('fs');
 
fs.readFile('TestFile.txt', function (err, data) {
    if (err) throw err;
 
    console.log(data.toString());
});

我们执行完读取档案操作,它会执行function,如果有错误,会回传错误;成功,会回传所读取的档案资料。如图:

同步读取档案

var fs = require('fs'); 
var data = fs.readFileSync('dummyfile.txt', 'utf8');
console.log(data);

写入文件(fs.writeFile() 写入档案,如果档案存在,会覆写原本档案资料;否则会自动新增档案并写入资料)

 fs.writeFile(filename, data[, options], callback)
 fileName:档案的完整路径及档名,格式字串。
● data:要写入的档案内容。
● options: options可能是一个物件或字串,包含"编码"及"flag"。这里预设的编码是utf8 , flag是"w"。
● call back:只带一个错误参数err的function,当我们执行writeFile完成时,要做的事。例如:写入成功的讯息显示;失败时,丢出err。

开启档案

fs.open(path, flags[, mode], callback)
path: 档案的完整路径及档名,格式字串。
flag: 用flag代表操作行为。可以参考下图!
mode: mode代表文件的权限,预设为0666代表可读可写。
call back: 是带两个参数的function,err及file data,当我们执行open完成时, 要做的事, 例如: 打开成功的讯息显示;失败时,丢出err。

开启读取档案

fs.read(fd, buffer, offset, length, position, callback) 
fd: 透过fs.open() 方法返回的文件描述符。
buffer: 数据写入的缓冲区。
offset: 缓冲区写入的写入偏移量。
length: 要从文件中读取的字元数。
position: 文件读取的起始位置,如果position 的值为null,则会从当前文件游标的位置读取。
callback:回呼函式,有三个参数err, bytesRead, buffer。
err为错误讯息, bytesRead表示读取的字元数,buffer为缓冲区对象

关闭

fs.close(fd, callback)
fd:透过fs.open()方法返回的文件描述符。
 call back:只带一个错误参数err的function,当我们执行close完成时,要做的事。例如:失败时,丢出err。

删除文件

fs.unlink(path, callback);删除存在的文件。
path:档案路径。
callback:只带一个错误参数err的function,当我们执行unlink完成时,要做的事。例如:删除成功的讯息显示;失败时,丢出err。

更多资讯:https://nodejs.org/dist/latest-v8.x/docs/api/readline.html

代码调试工具(主要推荐阮一峰介绍的调试工具)

Node.js 内建的debugger

1、进入command prompt 执行debugger

node inspect orfile.js

2、此时,可以看到程式进入debugging 模式。你可以看到>符号,指向目前debugging 的程式行

3、.我们可以再在debug>输入next (或n),debugging下一个程式区段

4、如果我们想要执行到下一个debugger; ,则在debug>输入 cont (或c)

设定中断点break-point
setBreakpoint(), sb() – 设定中断点于目前所在行数
setBreakpoint(line), sb(line) – 设定中断点给特定行数
setBreakpoint(‘fn()’), sb(…) – 设定中断点在函式的第一句
setBreakpoint(‘script.js’, 1), sb(…)– 设定中断点,在指定档名的第一行。(用于程式中有载入别的档案时)
clearBreakpoint(‘script.js’, 1), cb(…)– 清除中断点,在指定档名的第一行。(用于程式中有载入别的档案时)

watch, watchers
在debug过程中,想要查看一些资讯,例如,变数/参数…,可以用watch(“exp")
删除某项watch资讯,则,可用 unwatch(“exp")

常用的内建debug指令:
next, n执行至下一行。
cont, c继续执行并停在下一个debuggers;
step, s进入函式逐一除错。
out Step, o跳出函式的逐一除错。
watch加入表示式及变数至watch
watcher查看所有被加入的watch的值。
Pause暂停执行程式。
更多资讯:
http://www.ruanyifeng.com/blog/2018/03/node-debugger.html
https://nodejs.org/dist/latest-v8.x/docs/api/inspector.html

事件监听

自定触发及监听函式
Javascript 事件绑定通常使用addlistener,通常触发事件范围会有限,像通常使用的事件绑定,click, hover, focus, blur..
eventEmitter:自定义事件触发
事件名称可以任意取名,通常我们用驼峰式命名法,但也不限定
函式可以被附加在这个物件,当物件被执行时,触发这个函式,这些函式叫监听函式

// get the reference of EventEmitter class of events module
var events=require('events');
//create an object of EventEmitter class by using above reference.
var em=new events.EventEmitter();
//綁定事件函式
em.on('FirstEvent',function(data){
    console.log('First subscriber:'+data);
});
//emit觸發事件
em.emit('FirstEvent','我已經進入了第一事件的監聽函式!');

上述例子,我们先建立一个events.EventEmitter 物件,叫做em,然后,我们再绑定事件处理函式用on(),最后用emit触发事件

addListener()的方法,去自订触发事件:

var emitter=require('events').EventEmitter;
var em=new emitter();

em.addListener('FirstEvent',function(data){
    console.log('First Scriber: '+data);
});

em.on('SecondEvent',function(data){
    console.log('Second Scriber:'+data);
});

em.emit('FirstEvent',"這是第一個監聽式!");
em.emit('SecondEvent',"這是第二個監聽式!");

有二种EventEmitter 使用上的常见模式:从函式return EventEmitter 物件;继承EventEmitter 类别
从函式回传EventEmitter物件(也就是emit可以写在function里)

var emitter=require('events').EventEmitter;

function LoopProcessor(num){
    var e = new emitter();
    setTimeout(function(){
        for(var i=1;i<=num;i++){
            e.emit('BeforeProcess',i);
            console.log('Processing number : '+i);
            e.emit('AfterProcess',i);
        }
    },2000);
    return e;
}

var lp=LoopProcessor(3);
lp.on('BeforeProcess',function(data){
    console.log('About to start the process for '+data);
});
lp.on('AfterProcess',function(data){
    console.log('Completed processing '+data);
});

执行结果:

继承EventEmitter 类别(我们可以用util.inherits(),它是utility module的方法,所以,一开始就必须用require(‘util’)载入该模组)

var emitter = require('events').EventEmitter;
//繼承時, 需要用到的模組 
var util = require('util');
 
function LoopProcessor(num) {
    var me = this;
 
    setTimeout(function () {
 
        for (var i = 1; i <= num; i++) {
            me.emit('BeforeProcess', i);
 
            console.log('Processing number:' + i);
 
            me.emit('AfterProcess', i);
        }
    }
    , 2000)
 
    return this;
}

//直接讓LoopProcessor 繼承 emitter 類別
util.inherits(LoopProcessor, emitter)
 
var lp = new LoopProcessor(3);
 
lp.on('BeforeProcess', function (data) {
    console.log('About to start the process for ' + data);
});
 
lp.on('AfterProcess', function (data) {
    console.log('Completed processing ' + data);
});
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容

  • 本文由我首发于 GitChat 中。 前言 在 Node.js 开发领域中,原生 C++ 模块的开发一直是一个被人...
    機巧死月不會碼代碼阅读 5,215评论 6 24
  • 总结一: [node.js总结](http://www.cnblogs.com/Darren_code/archi...
    xiumeiii阅读 1,883评论 0 14
  • Node.js是目前非常火热的技术,但是它的诞生经历却很奇特。 众所周知,在Netscape设计出JavaScri...
    Myselfyan阅读 4,062评论 2 58
  • # 模块机制 node采用模块化结构,按照CommonJS规范定义和使用模块,模块与文件是一一对应关系,即加载一个...
    RichRand阅读 2,482评论 0 3
  • 今晚抛下家人和客户吃饭聊合作,也许是酒精作用(因为要开车我没喝酒),客户聊起来他年轻时候事情,他说他家在八十...
    royhsu阅读 174评论 0 0