废话篇:
对于我这个新手的不能再白菜的人来说,nodejs的大名都有耳闻,所以说他是一项不可不克服的技能也是可以说的。但是之前没有搞清楚的情况之下胡乱的猜测,是的我对node.js没有一个具体的概念的形成也是吃了不少的苦头,现在就让我们来吧它弄清楚吧。。。
正文篇:
1.了解Node.js概念。
-node.js基本概念
-CommonJs概念
2.Node.js中的npm的学习。
-install中的本地和全局
-uninstall命令简介
3.package.json简介
4.Node.js详尽学习
一:让我们来了解node.js的基本概念吧。
我想很多的新手像我之前一样,看了很多的XXX.js的javascript封装的东西。然后就想当然的认为node.js也是其中的一员,然后就在他们说什么服务器javascript和布置开发环境之类的东西之后完全的懵逼了有木有啊。然后我就在这种傻愣的情况之下来学习了node.js了。因为实在受不了自己的傻缺了。。。。。还有就是为了紧跟先驱们的脚步啦。。
----nodejs简介: node.js并不是我们所想象的是一个由js封装的模块文件或者是其他什么的,他和js最主要的关联实际上就是为服务器运行javascript带来可能。用专业一点的话说就是-- Node.js 是一个平台,建立在 Chrome JavaScript 运行时之上,目的是建立快速、可伸缩的网络应用。Node.js使用事件驱动,非阻塞的 I/O 模式,这使得他是轻量而高效的,能够在分布设备上完美运行高数据吞吐的实时应用。,然后就没有然后了。node.js实际上是用C++写的,主要的功能是运行时环境的提供(就有点类似与tomcat这一类的web服务器一样,也是为了提供运行环境。)。那么为什么要实现这样一个运行环境来进行服务器端的js的运行呢,因为js是一门不论是执行速度还是灵活性都十分出色的语言啊(他们这么说的,实际到底怎么回事谁管他啊,只要知道能这么做就好了。)
安装好node之后(至于安装的方式,就劳烦大家自己找了咯。)我们首先来看一下其中的文件有些什么分别有什么用:
以上就是全部的文件了。实际上主要的部分就是node.exe了,还有两个文件需要特别注意的是node_modules,这个文件夹是存放下载到本地的js模块文件的。还有一个就是npm.cmd批处理文件,那什么是npm呢。npm实际上是以个模块管理器,这也是node.js的内里所在,开发者关注与自己的主题内容,而其他事情都可以有相关的模块来进行操作,这也就是体现了模块化的魅力。之后我们会和它进行长篇的交流,现在先对于当前的内容进行简单的说明而已。
打开cmd之后就可以开始使用node了,查询当前的node版本:
当然还有如下的命令行可以使用
如要看文档可以去https://nodejs.org/
----CommonJs简介:我想对于前段来说一定听说过吧,这里也要角整一个误区,CommonJS实际上也不是一个什么js封装模块,而是一个规范,专门针对于模块化编程的。对于现在的前端来说,已经不再只是需要单一的验证功能了,有许多的功能实际上前段就可以完成了,但是对于越来越庞大的前端代码来说模块化的编程将会大大的增强代码的可读性和可复用性。对于开发者来说不得不说是一种急需的转变,CommonJs就是针对于这样的大环境所提出的一套规范。
CommonJS希望JS在任意的地方都可以运行。CommonJS定义了在实现模块化的内容的时候需要使用到的模块内容包括:模块引用(require),模块定义(exports),模块标识(module),require()用来引入外部模块;exports对象用于导出当前模块的方法或变量,唯一的导出口;module对象就代表模块本身。这里要重点的说一下exports和moduel的关系,实际上exports可以看成moduel对象可以在外部调用的接口的关系。就类似于java中的类和类中的public属性和方法一样的概念。示例代码:
//sum.js exports.sum = function(){...做加操作..}; //calculate.js var math = require('sum'); exports.add = function(n){ return math.sum(val,n); };
二:好了,接下来我们来重点一下学习npm吧。
npm实际上是包含在Node.js中的一部分,但是也是最为重要的一部分。npm是node.js的模块管理器。首先(第一)NPM允许用户从其本身的库中下载其他人写好了的第三方模块包到本地来使用。其次(第二)其允许用户从NPM服务器中下载他人编写的命令行程序到本地使用。最后(第三)同样的我们自己也是可以将编写好了的文件包或是命令行上传到NPM上的供他人使用的。这将大大变化我们的变成所需要花费的时间,并且集中了更多人的想法,用户可以针对自身的条件选取适合我们当前需求的功能模块。
npm的操作界面不二样的同样是命令行,现在让我们来看看它的常用命令吧。(图为npm说明文字,我们这里只挑极为常用的基础命令来讲。)
--install的本地和全局:首先install命令可以用来直接重网上下载我们需要的模块到本地。命令行的形式可以写成 npm install <moduel_name>。
npm install express //从默认的地址下载express模块包到本地 npm --registry "http://..." install express //从registry指令表示的地址下载express模块包到本地。
在下载模块包的时候我们还应考虑到时本地安装还是应该全局安装。
----但是什么是本地安装,什么是全局安装呢?
1.首先全局安装的命令行是这样的
npm install express -g
和平常的载入最为主要的区别在与其之后需要加入-g这一全局标识。而这一表示的含义是将会吧程序包安装在全局环境中,即NODE_PATH指定的文件夹中。一般可以使用npm root -g查看全局安装目录。
全局安装后可以供命令行(command line)使用,用户可以在命令行中直接运行该组件包支持的命令。之前我们也提到过,我们也可以从NPM上面下载命令行程序到本地来使用,而 这一类的程序就最好使用全局安装的形式。
2.下面来说明一下本地安装:
npm install gulp
npm install gulp --save-dev
以上两条命令行都是安装程序包到本地,其实际的安装地点是当前的用户打开的文件夹下面,安装的时候会自动的在当前的文件夹中添加一个node_moduel文件夹,并把相关组件安装在这一文件夹内。想要调用下载到本地的内容的话我们可以直接通过代码中使用,就像之前的例子中的var sum = require("express");所以说本地安装,是当我们需要在代码中调用这一模块的功能的时候。
当然在一些特殊的情况我们需要说明一下,由于某些模块程序对于另外一些程序的依赖,可能每一次的版本对于依赖的程序要求的版本也是不相同的,并且每一次的更新可能意味着功能的不同。如果是本地安装的话因为会有单独的文件,用户依据不同的需求下载不同版本的文件。而全局的变量则都是统一下载在同一个文件中的,所以可能需要我们对于统一程序的不同版本进行管理,这样将会麻烦许多。
--uninstall简介:有install,坑定就有uninstall(卸载模块),代码如下:
npm uninstall gulp --save-dev
删除本地安装的gulp模块包。
还有其他的许多的命令行可以自行查看:
推荐链接连接如下:http://www.cnblogs.com/PeunZhang/p/5553574.html。
三:package.json简介
如果打开我们下载的模块包就可以发现,我们的每个模块包中都有一个叫做package.json的文件,打开着一个文件,内容如下。
·
可以看见,当前文件存储了许多的对于当前的模块包的相关的额信息内容,包括名称版本和相关的额依赖等等,这里就不细说每一个属性标明的相关的信息是指什么,网上随便一搜就有许多了。这里就简单带过了。
4.NodeJs详尽学习(详尽学习部分实际上有许多的概念,这里只是列一个总章节,之后会书写简单介绍和放制具体内容的连接。)
内容很多,所以又要列目录了。。。
- node.js REPL(交互式解释器)
- node.js模块机制详解
- node.js事件机制
- node.js异步I/O实现
REPL(交互式解释器):在使用cmd的时候我们可以通过node指令直接跳转到REPL来直接进行代码的编辑运行。它可以执行包括 读取(读取用户输入,解析输入了Javascript 数据结构并存储在内存中。), 执行(执行输入的数据结构),打印(输出结果),循环(循环操作以上步骤直到用户两次按下 ctrl-c 按钮退出)。
常用指令包括:
-
ctrl + c - 退出当前终端。
-
ctrl + c 按下两次 - 退出 Node REPL。
-
ctrl + d - 退出 Node REPL.
-
向上/向下 键 - 查看输入的历史命令
-
tab 键 - 列出当前命令
-
.help - 列出使用命令
-
.break - 退出多行表达式
-
.clear - 退出多行表达式
-
.save filename - 保存当前的 Node REPL 会话到指定文件
-
.load filename - 载入当前 Node REPL 会话的文件内容。
node.js模块机制详解:
在我们使用nodeJS的时候,虽然我们汇编写如下的代码:
1 var p = document.getElementById("xxx"); 2 3 function changeP (content){ 4 p.innerHTML = content; 5 console.log("当前的内容是Content"); 6 } 7 8 exports.changeP = changeP;
乍看之下是分享是在全局变量中进行相关的编写,但是实际情况是,在我们使用require函数来进行模块加载的时候,node会把这一代码块看成是一个模块并进行相关的封装。现在只是简单的说一下,下面开来更详细的解释。
Node中实际上室友原生模块和文件模块之分的,原生模块在编译的时候就已经加入了二进制执行文件中了,可以最为快速的程序服务。而文件模块是我们启用服务最为常用的部分内容,县来讲一下文件模块是怎么加载的吧。在我们加载文件进行内容的运行的时候,实际上是通过node的原生模块中的module来进行加载的,在module中有一个runMain的今天方法其实主要的。
// bootstrap main module. Module.runMain = function () { // Load the main module--the command line argument. Module._load(process.argv[1], null, true); };
_load静态方法在分析文件名之后执行
var module = new Module(id, parent);
并根据文件路径缓存当前模块对象,该模块实例对象则根据文件名加载。
module.load(filename);
实际上在文件模块中,又分为3类模块。这三类文件模块以后缀来区分,Node.js会根据后缀名来决定加载方法。
- .js。通过fs模块同步读取js文件并编译执行。
- .node。通过C/C++进行编写的Addon。通过dlopen方法进行加载。
- .json。读取文件,调用JSON.parse解析加载。
在我们加载文件模块的时候node调用一个类似于eval的runInThisContext函数,将我们的文件模块代码打包成为一个function对象,最后传入module对象的exports,require方法,module,文件名,目录名作为实参并执行。这样我们就可以获取一个实际参数形式的模块对象。代码如下:
1 (function (exports, require, module, __filename, __dirname) { 2 var circle = require('./circle.js'); 3 console.log('The area of a circle of radius 4 is ' + circle.area(4)); 4 });
其中的module参数实际上穿传入的是当前实例自身,这个需要记住。
在这个主文件中,可以通过require方法去引入其余的模块。而其实这个require方法实际调用的就是load方法。
load方法在载入、编译、缓存了module后,返回module的exports对象。这就是circle.js文件中只有定义在exports对象上的方法才能被外部调用的原因。
node事件机制:
Event模块是一个简单的时间监听器模式的实现,单与客户端不相同的是,其并不是DOM事件,没有冒泡和模块逐层深入等特性。其类似于钩子。是的我们并不需要注意到时间是什么时候除法的,而只需要注意事件再触发的时候我们需要做一些什么样的事情或是逻辑。同时还有一点需要注意的是,在一个事件上面绑定10个以上监听器的时候,nodeJS会提示我们一个警告,这与NODEJS的单线程机制有关,认为太多监听可能会导致内存的泄漏。当然我们也可以通过emitter.setMaxListeners(0)来进行改变。
事件的继承:node中封装好了相关的方法来进行继承。
1 function Stream(){ 2 events.EventEmitter.call(this); 3 } 4 5 util.inherits(Stream, events.EventEmitter);
对于多事件的协调工作,通过异步机制使请求无阻塞,达到并行请求的目的。我看到的拥有这协调方案的解决方式有jscex和EventProxy。
还有一个要注意的事情是多时间同时间处理的时候,当缓存没有效果的时候,高并发访问数据库的情况,可能造成数据库的雪崩问题。所以对于数据库的这一问题,我们可以使用事件队列这一方式来进行解决。在事件触发的识货对于有数据库需求的数据,进行如队列,然后再某一个事件处于需要操作数据库的时候讲数据库的可查询状态改变成为不可查,然一个查询完成之后,在进行第二个查询任务,这样就可以解决这一个问题。
node异步I/O介绍:
这里我们稍微的介绍一下异步I/O和同步I/O,阻塞I/O和非阻塞I/O。
首先是阻塞I/O:实际上就是在执行I/O操作的时候主题程序先进入阻塞状态然后等I/O操作结束的时候在进行操作。
非阻塞I/O:就是在执行I/O操作的时候并不阻断当前的程序的执行而是挂起需要I/O数据的那一段,然后本机对于其他的程序进行操作,当获取到需要的数据的时候在讲挂起的一段进行运算。可能出现数据获取不正确的情况发生,需要应用多次的进行多次判断。
当然同步I/O:阻塞I/O的调用状态就是一种同步。
而异步I/O:类似于非阻塞状态的I/O操作。这操作需要主体程序主动的对于I/O操作有一个轮询的操作,这样的话才能确保获取的数据是正确的。
当然nodeJS不仅仅是想我上述说的这样这么简单,想要真正的学号需要我们多写多看。之后也会放出链接,分别编写具体的每一个点的内容。