本文实例讲述了Node 模块原理与用法。分享给大家供大家参考,具体如下:

简介

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包:

  1. express
  2. request (后端发送请求的模块)
  3. cheerio (像前端一样操作拉取回来的数据)

爬虫以及Robots协议介绍:

  1. 爬虫,是中自动获取网页内容的程序。是搜索引擎的重要组成部分,因此搜索引擎优化很大程度上就是针对爬虫而做出的优化。
  2. 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 在文件有变化之后会自动重启服务

希望本文所述对大家node.js程序设计有所帮助。

Node 模块原理与用法详解的更多相关文章

  1. 利用Node实现HTML5离线存储的方法

    这篇文章主要介绍了利用Node实现HTML5离线存储的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  2. ios – 使用带有NodeJs HTTPS的certificates.cer

    我为IOS推送通知生成了一个.cer文件,我希望将它与NodeJSHTTPS模块一起使用.我发现HTTPS模块的唯一例子是使用.pem和.sfx文件,而不是.cer:有解决方案吗解决方法.cer文件可以使用两种不同的格式进行编码:PEM和DER.如果您的文件使用PEM格式编码,您可以像使用任何其他.pem文件一样使用它(有关详细信息,请参见Node.jsdocumentation):如果您的文件使

  3. 如何在XCode IDE中构建NodeJS?

    如何在XCodeIDE中将NodeJS构建为项目?NodeJS构建指令说它应该用以下内容构建:但是我希望在XCodeIDE中构建.我真正想要做的是在我的应用程序中嵌入NodeJS,所以我想如果我可以在XCode中构建NodeJS,那么我可以调整它以在我建立和运行NodeJS后添加我的应用程序.我想通过让V8在XCode中编译来取得一些进展,现在我正在尝试将NodeJS添加到V8项目中.解决方法在节点存储库根目录中运行./configure–xcode,您将获得所需的node.xcodeproj文件.

  4. 深入云存储系统Swift核心组件:Ring实现原理剖析

    它的目的是用于托管Rackspace的CloudFilesservice,原始项目代号是swift,所以沿用至今。Ring是Swift中最重要的组件,用于记录存储对象与物理位置间映射关系。先来看一下Swift文档中关于Ring的描述:Ring用来确定数据驻留在集群中的位置。有单独对应于Account数据库、container数据库和单个object的ring。Ring使用zone的概念来保证数据的隔离。每个partition的replica都确保放在了不同的zone中。本文逐步深入探讨了Swift如何通过

  5. Swift开发:创建XML文件,包含节点,属性值

    .append;//3创建第二个节点数据letitem2:Item=Item;for{letnode=Node;node.id=i+1;node.attributes=["ID":"\","Name":"N-\","disp":"1","Appliance":"1","Icon":"ic_switch_4"]item2.addNode;}xml.items?

  6. 泛型 – 符合Swift中Comparable的泛型类

    我正在尝试创建一个符合Comparable协议的简单通用节点类,以便我可以轻松地比较节点而无需访问其密钥.当我试图写

  7. swift3 – 将SceneKit对象放在SCNCamera当前方向的前面

    >生成SCNVector4,它定向节点,使其“面向”相机?但是让我有点失落.我看到了许多类似的问题,比如thisone,但没有答案.嘿,如果要将对象放在相对于另一个节点的某个位置,并且与参考节点的方向相同,则可以使用这个更简单的函数:如果您想将’node’2m放在某个’cameraNode’前面,你可以这样称呼:

  8. 如何在Swift中继承NSOperation以将SKAction对象排队以进行串行执行?

    Rob为子类化NSOperation提供了agreatObjective-Csolution,以实现SKAction对象的串行排队机制.我在自己的Swift项目中成功实现了这一点.要使用Actionoperation,请在客户端类中实例化NSOperationQueue类成员:在init方法中添加以下重要行:然后当您准备好向其添加SKActions时,它们会连续运行:您是否需要在任何时候终止操作:希望有所帮助!

  9. 核心数据 – 如何在Swift中定义CoreData关系?

    在CoreData中,我已经从Node到Tag定义了一个无序的多对多关系.我创建了一个这样的Swift实体:现在我想添加一个Tag到Node的一个实例,像这样:但是,这会失败,并显示以下错误:Terminatingappduetouncaughtexception‘NSinvalidargumentexception’,reason:‘Unacceptabletypeofvalueforto-ma

  10. 将“nil”值赋给Swift中的一般类型变量

    您需要将变量声明为可选项:不幸的是,这似乎触发了一个未实现的编译器功能:您可以通过使用NSObject的类型约束声明T来解决它:

随机推荐

  1. Error: Cannot find module ‘node:util‘问题解决

    控制台 安装 Vue-Cli 最后一步出现 Error: Cannot find module 'node:util' 问题解决方案1.问题C:\Windows\System32>cnpm install -g @vue/cli@4.0.3internal/modules/cjs/loader.js:638 throw err; &nbs

  2. yarn的安装和使用(全网最详细)

    一、yarn的简介:Yarn是facebook发布的一款取代npm的包管理工具。二、yarn的特点:速度超快。Yarn 缓存了每个下载过的包,所以再次使用时无需重复下载。 同时利用并行下载以最大化资源利用率,因此安装速度更快。超级安全。在执行代码之前,Yarn 会通过算法校验每个安装包的完整性。超级可靠。使用详细、简洁的锁文件格式和明确的安装算法,Yarn 能够保证在不同系统上无差异的工作。三、y

  3. 前端环境 本机可切换node多版本 问题源头是node使用的高版本

    前言投降投降 重头再来 重装环境 也就分分钟的事 偏要折腾 这下好了1天了 还没折腾出来问题的源头是node 使用的高版本 方案那就用 本机可切换多版本最终问题是因为nodejs的版本太高,导致的node-sass不兼容问题,我的node是v16.14.0的版本,项目中用了"node-sass": "^4.7.2"版本,无法匹配当前的node版本根据文章的提

  4. nodejs模块学习之connect解析

    这篇文章主要介绍了nodejs模块学习之connect解析,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  5. nodejs npm package.json中文文档

    这篇文章主要介绍了nodejs npm package.json中文文档,本文档中描述的很多行为都受npm-config(7)的影响,需要的朋友可以参考下

  6. 详解koa2学习中使用 async 、await、promise解决异步的问题

    这篇文章主要介绍了详解koa2学习中使用 async 、await、promise解决异步的问题,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  7. Node.js编写爬虫的基本思路及抓取百度图片的实例分享

    这篇文章主要介绍了Node.js编写爬虫的基本思路及抓取百度图片的实例分享,其中作者提到了需要特别注意GBK转码的转码问题,需要的朋友可以参考下

  8. CentOS 8.2服务器上安装最新版Node.js的方法

    这篇文章主要介绍了CentOS 8.2服务器上安装最新版Node.js的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  9. node.js三个步骤实现一个服务器及Express包使用

    这篇文章主要介绍了node.js三个步骤实现一个服务器及Express包使用,文章通过新建一个文件展开全文内容,具有一定的参考价值,需要的小伙伴可以参考一下

  10. node下使用UglifyJS压缩合并JS文件的方法

    下面小编就为大家分享一篇node下使用UglifyJS压缩合并JS文件的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

返回
顶部