简介
V8引擎自身就是用于Chrome浏览器的JS诠释部份,然则Ryan Dahl,把V8搬到效劳器,用于做效劳器的软件。
Node是一个专注于完成高机能Web效劳器优化的专家,在碰到V8而降生的项目
- 没有汗青包袱,没有同步I/O。不会涌现一个同步I/O致使事宜轮回机能急剧下降的状况。
- V8机能足够好,远远比Python,Ruby等别的脚本言语的引擎快。
- JavaScript言语的闭包特征异常轻易,比C中的回调函数好用。
Node可以让JavaScript运转在效劳器端的平台开辟,它让JavaScript的触角延长到了效劳器端,可以与PHP,JSP,Python,Ruby等言语完成后端开辟。
但Node好像有点差别:
- Node不是一种自力的言语,与PHP,JSP,Python,Perl,Ruby的“纵然言语,也是平台”差别,Node运用的是JavaScript举行编程,运转在JavaScript引擎上(V8)
- 与PHP,JSP等比拟(PHP,JSP,.net都须要运转在效劳器顺序上,Apache,Naginx,Tomcat,IIS),Node跳过了Apcahe,Naginx,IIS等HTTP效劳器,它自己不必竖立在任何效劳器任何之上。Node的设想理念与典范架构(LAMP = Linux + Apache + MySQL + PHP) 有着很大的差别,可以供应壮大的伸缩才。
- Node没有Web容器。
- Node是花最小的硬件本钱,寻求更高的并发,更高的处置惩罚机能。
Node特性
所谓特性,就是Node假如处理效劳器高机能瓶颈题目。
JavaScript有什么特性的时候,会马上想到 单线程
,事宜驱动
, 面向对象
。然则JavaScript精华 以为是 this
, 闭包
,作用域链
, 函数
。才使得这门言语魅力无限。
单线程
在Java,PHP,或许.net 等效劳器端言语中,会为每一个用户端衔接竖立一个新的线程。而每一个线程须要消耗约莫2MB内存。理论上,一个8GB内存的效劳器可以同时衔接的最大用户数4000个摆布。要让Web应用顺序支撑更多的用户,就须要增添效劳器的数目,而Web应用顺序的硬件本钱就上升了。
Node不为每一个用户衔接竖立一个新的线程,而仅仅运用一个线程。当有用户衔接了,就触发一个内部事宜,并经由过程非壅塞I/O,事宜驱动机制,让Node顺序宏观上也是并行的。Node中,一个8GB内存的效劳器,可以同时处置惩罚凌驾4万用户的衔接。
单线程优点:操纵系统完全不再有线程竖立,烧毁的时候开支。
单线程害处:就是一个用户形成了线程的奔溃,悉数效劳都奔溃了,别的人的效劳也就奔溃了。
单线程也可以形成宏观上的“并发”。
非壅塞I/O
非壅塞I/O non-blocking I/O
例子:接见数据库获得数据的时候,须要一段时候。
在传统的单线程处置惩罚机制中,在实行了接见数据库代码以后,悉数线程都将停息下来,守候数据库返回结果,才实行背面的代码。也就是说I/O壅塞了代码的实行,极大下降了顺序实行的效力。
Node采用了非壅塞型I/O机制,因而在实行了接见数据库的代码以后,将马上转而实行背面的代码,把数据库返回的结果的处置惩罚代码放在回调函数中,从而进步了顺序的实行效力。
当某个I/O实行终了时,将以时候的情势关照实行I/O操纵的线程,线程实行了这个事宜的回调函数。为了处置惩罚异步I/O,线程必需有事宜轮回,不停的搜检是不是有未处置惩罚的时候。顺次予以处置惩罚。
壅塞形式下,一个线程只能处置惩罚一项使命,要想进步吞吐量必需经由过程多线程。而非壅塞形式下,一个线程永远在实行盘算操纵,这个线程的CPU中心应用率永远是100%。 有一种相似 : 与其多人事情,然则好多人闲着,倒不如一个人事情,往死里干活。
事宜驱动
事宜驱动 event-driven
在Node中,客户端要求竖立衔接,提交数据等行动,会触发相应的时候。在Node中,在一个ie时时候,只能实行一个事宜回调函数,然则在实行一个事宜回调函数的半途,可以转而处置惩罚别的事宜(比方:有新用户衔接),然后返回继承实行原事宜的回调函数。这类处置惩罚机制,称为:”事宜环”机制。
Node底层是C++(V8也是C++) 编写。底层代码中,近折半都用户事宜行列,回调函数行列的构建。用事宜驱动来完成效劳器的使命调理。用一个线程,担当起了处置惩罚异常多的使命。
单线程,削减内存开支,操纵系统的内存换页。
如某一个使命,实行了,然则被I/O壅塞了,所以这个县城就壅塞了。非壅塞I/O,不会傻等I/O语句完毕,而会实行背面的语句。应用事宜驱动,不管是新用户的要求,照样老用户的I/O完成,都将以事宜体式格局到场事宜环中,守候调理。
Node一切的I/O都是异步的,回调函数嵌套回调函数。
Node是单历程单线程应用顺序,然则经由过程事宜和回调支撑并发,所以机能异常高。
Node的每一个API都是异步的,并作为一个自力线程运转,运用异步函数挪用,并处置惩罚并发。
Node基本上一切的事宜机制都是用设想形式中的观察者形式完成的。
Node单线程相似进入一个while(true)的事宜轮回,直到没有事宜观察者退出,每一个异步事宜都天生一个事宜观察者,假如有事宜发作就挪用该回调函数。
模块
moduel
Node中,以模块为单元分别一切功用,而且供应一个完全的模块加载机制,可以将应用顺序话费为各个差别的部份。
Node中,一个JavaScript文件中定义的变量,函数,都只在这个文件内部有结果。
侠义的说,每一个JavaScript文件都是一个模块,而多个JavaScript文件之间可以互相require,配合完成一个功用,整体外对,又称之为广义上的模块
优点:
- 削减反复代码量,增添可读性。
- 轻易举行代码计划。
- 方面运用第三方模块。
当须要从JS文件外部援用到这些变量,函数时,必需运用exprots对象,或许module.exprots举行暴露。运用者须要运用require(); 函数引入这个JS文件。
function People( name,sex,age ){
this.name = name;
this.sex = sex;
this.age = age;
}
People.prototype = {
sayHello: function(){
console.log(this.name+this.sex+this.age);
}
};
// 暴露
module.exports = People;
// 运用
var People = require('./People.js');
var p1 = new People('zf','nv','23');
p1.sayHello();
一个JavaScript文件,可以向外exprots无数个变量,函数,对象,然则require(); 的时候,仅仅须要 载入一次JS文件即可。 所以,无形以后,会增添一个顶层定名空间。
// 变量
// 须要变量援用 运用
exports.a = 10;
// 直接须要变量值运用.
module.exports = name;
// 对象
module.exports = {
name1: 123,
name2: 456
}
// 暴露结果: { name1: 123, name2: 456 }
exports.msg = {
name1: 1,
name2: 2
}
// 暴露结果 : { msg: { name1: 1, name2: 2 } }
// 函数
exports.showMsg = function () {
}
// 暴露结果 : { showMsg: [Function] }
// 在 援用结果 须要 经由过程 变量 援用对象 实行
// var msg = require();
// msg.showMsg();
module.exports = function () {
}
// 暴露结果 [Function]
// 引入文件的 变量 直接实行
模板引擎
数据绑定,成为一个完全的HTML字符串。
Node中运用的模板:ejs 和 jade
背景模板引擎:
<ul>
<% for(var i = 0 ; i < news.length ; i++){ %>
<li><%= news[i] %></li>
<% } %>
</ul>
// 模板中须要的数据
var dictionary = {
a:6,
news : ["xixi","haha"]
};
HTTP模块
主要类
Class: http.Server
var server = http.createServer();
server
就是http.Server
类的实例。
经常使用的要领有:
server.listen(port, [hostname], [backlog], [callback])
Class: http.ServerResponse
var server = http.createServer(function(req,res){ });
res
就是 http.ServerResponse
类的实例。
Class: http.IncomingMessage
“
var server = http.createServer(function(req,res){ });
“req
就是http.IncomingMessage
类的实例。
server对象
可以运用on语法监听某个事宜。
var http = require('http');
var server = http.createServer();
server.on('request',function ( req,res ) {
res.setHeader('Content-type','text/html;charset=utf8');
if ( req.url == '/' ){
res.end('index');
} else {
res.end('404');
}
});
server.listen(8080,'localhost');
req对象
每次上行要求头对象
req.headers //HTTP上行要求头
req.httpVersion // http要求的版本。如今基本上都是1.1
req.method // “GET”、”POST”就是要求的范例
req.url // 用户要求的网址
res对象
每次下行相应对象
res.end() // 每次都要有这个语句,示意此次的发送已完毕
// 参数必需是string、buffer(图片、文件)。
res.write() // 就是写HTTP下行要求的body
res.setHeader() // 设置返回的报文头部
res.statusCode = 404; // 设置状况码
res.writeHead() // 和res.setHeader差不多
res.writeHead(288 , {"Content-Type":"text/plain"});
url模块
作用内置模块,剖析url,剖析地点。 剖析和剖析 URL 的东西
url.parse()
url.parse()
就是用来剖析网址,吸收一个字符串,返回一个JSON:
var obj = url.parse("http://localhost:8080/a/b/c/1.html?name=ting&age=21");
url.parse要领第二个参数假如是true,那末返回的对象中的query就是json
query: { xingming: 'xiaoming', age: '12' }
querystring模块
querystring模块是特地用来剖析GET要求的查询字符串的。
console.log( qs.parse('name=ting&age=21&hobby=run&hobby=sing') );
// 返回:{ name: 'ting', age: '21', hobby: [ 'run', 'sing' ] }
path模块
处置惩罚和转换文件途径的东西集,特地处置惩罚途径
path.basename() 返回途径中的文件名
path.dirname() 返回途径中的文件夹名
path.extname() 返回途径的拓展名
console.log( path.basename('/xixi/haha/a.html') ); //a.html
console.log( path.extname('/xixi/haha/a.html') ); //.html
console.log( path.dirname('/xixi/haha/a.html') ); ///xixi/haha
fs模块
文件处置惩罚模块,可以读文件,也可以写文件
fs.readFile(); //读取文件内容
fs.readDir(); //读取文件夹名
fs.appendFile(); //追加文件
fs.writeFile(); //写入文件(掩盖原有的)
fs.rename(); //修正文件名
自定义模块
每一个js文件中可以看成是一个小小的模块
require()谁,就会实行谁。就相当于挪用一个函数。A require B, 先实行B悉数语句,然后实行A的盈余语句。
require('./test/a.js');
每一个js文件就是一个闭包,声明的函数、变量只在这个js文件内部有定义。
A require了 B , 那末B内里的一切途径都要根据A的途径写。
假如须要运用到别的文件中的变量,运用exports暴露出去。
exports.*** = ***;
testA .js
var a = 100;
exports.a = a;
主文件
var testA = requrie('./testA.js');
console.log( testA.a );
暴露唯一的接口,module.exports ,平常运用到组织函数。
假如只要写文件载入,会去默许文件夹下:node_modules 寻觅是不是有当前须要载入的文件
require('test.js');
也可以直接省略途径、省略文件名,只写文件夹名
require('aa');
实际上援用的是node_moduels文件夹内里的aa文件夹内里的index.js文件。
平常第三方模块,都放入node_modules文件夹中。
package.json
设置信息:
{
"name": "my_package", //项目名字
"version": "1.0.0", //版本号
"main": "index.js", //进口文件
"keywords": [], //关键词,就是搜刮什么npm上可以显现你
"author": "ag_dubs", //作者
"license": "ISC", //版权协定
"repository": { //代码托管堆栈,这个会自动天生一个衔接
"type": "git",
"url": "https://github.com/ashleygwilliams/my_package.git"
},
"bugs": { //假如发明bug应当交给谁
"url": "https://github.com/ashleygwilliams/my_package/issues"
},
"dependencies": {
"underscore": "*",
"date-format" : "0.0.2"
},
"homepage": "https://github.com/ashleygwilliams/my_package" //个人网站
}
最主要的信息是:依靠
{
"dependencies": {
"underscore": "*",
"date-format" : "^0.0.2"
}
}
formidable
处置惩罚POST要求
// formidable 语法
var form = new formidable.IncomingForm();
// 设置上传途径
form.uploadDir = "./uploads";
form.parse(req, function(err, fields, files) {
// fields是一般域,就是一般的文本框、单选按钮、复选按钮、textarea都存在这个对象内里
// files是上传的文件信息
var newname = df('yyyyMMddhhmmssSSS', new Date());
fs.rename(files.touxiang.path , "./uploads/" + newname + ".jpg",function(err){
if(err){
res.end("error");
return ;
}
});
res.end("ok");
});
爬虫低级
须要的npm包:
- express
- request (后端发送要求的模块)
- cheerio (像前端一样操纵拉取回来的数据)
爬虫以及Robots协定引见:
- 爬虫,是中自动猎取网页内容的顺序。是搜刮引擎的主要组成部份,因而搜刮引擎优化很大程度上就是针对爬虫而做出的优化。
- robots.txt是一个文本文件,robots.txt是一个协定,不是一个敕令。robots.txt是爬虫要检察的第一个文件。robots.txt文件通知爬虫在效劳器上什么文件是可以被检察的,搜刮机器人就会根据该文件中的内容来肯定接见的局限。
var express = require('express');
var app = express();
var cheerio = require('cheerio');
app.get('/', function(req, res){
var request = require('request');
request('https://linxingzhang.com', function(err, response, body) {
if (!err && response.statusCode == 200) {
$ = cheerio.load(body); // 和jquery的$('body') 一样
res.json({
panel: $('#link-panel li').length
});
}
});
});
app.listen(3000);
运用supervisor
启动
> supervisor start app.js
经常使用npm包
模块名 | 链接地点 | 简介 |
---|---|---|
async | async | 异步操纵治理 |
bl | bl | 二进制数据剖析 |
bluebird | bluebird | 异步操纵治理 |
browserify | browserify | 宣布浏览器可用的包 |
bunyan | bunyan | 日记(logging)治理 |
chai | chai | 断言 |
chalk | chalk | 敕令行彩色输出 |
co | co | 异步流程治理 |
colors | colors | 敕令行彩色输出 |
commander | commander | 敕令行东西 |
debug | debug | Debug输出器 |
dockerode | dockerode | Docker治理 |
duplexify | duplexify | Stream流操纵东西 |
event-stream | event-stream | Stream流操纵东西 |
express | express | Server效劳器框架 |
hapi | hapi | Server效劳器框架 |
koa | koa | Server效劳器框架 |
glob | glob | 文件名婚配 |
grunt | grunt | 构建东西 |
gulp | gulp | 构建东西 |
hyperquest | hyperquest | 轻量级HTTP客户端 |
istanbul | istanbul | 测试用例掩盖率剖析 |
JSONStream | JSONStream | Stream流治理东西 |
levelup | levelup | LevelDB |
lodash | lodash | 函数式编程东西 |
log4js | log4js | 日记(logging)治理东西 |
minimatch | minimatch | 文件名婚配 |
minimist | minimist | 敕令行操纵 |
mocha | mocha | 单元测试 |
moment | moment | 日期时候输出 |
mongodb | mongodb | MongoDB |
mysql | mysql | MySQL |
nconf | nconf | 设置东西 |
needle | needle | 轻量级HTTP客户端 |
node-fetch | node-fetch | Fetch API |
nodemailer | nodemailer | Email客户端 |
passport | passport | 登录和认证 |
pg | pg | Postgres |
pump | pump | Stream流治理东西 |
redis | redis | Redis |
request | request | HTTP客户端 |
restify | restify | REST API搭建 |
socket.io | socket.io | WebSocket及时通讯 |
split2 | split2 | Stream流治理东西 |
tape | tape | 单元测试 |
through2 | through2 | Stream流治理东西 |
underscore | underscore | 函数式编程东西 |
ws | ws | Websockets |
xml2js | xml2js | XML转换为JavaScript |
http-server | http-server | 敕令行的HTTP效劳器 |
nrm | nrm | 变动NPM下载源 |
node-inspector | node-inspector | Node调试 |
supervisor | supervisor | 检测Node历程的效劳 |
nodemon | nodemon | 在文件有变化以后会自动重启效劳 |