手记

Node.js基础---node概念

node概念

node.js是基于Chrome V8引擎的javaScript运行环境,
node.js使用了一个事件驱动,非阻塞I/O的模型,使其轻量又高效;
node.js的包管理器是npm
node.js适合密集型高并发、I/O 密集场景性能高,也就是 Web 场景性能高主要也是解决这个问题;

一,阻塞
线程在执行中如果遇到磁盘读写,网络通讯(统称为I/O操作),通常是耗时比较长的,这时操作系统会剥夺这个线程的CPU控制权,使其暂停执行,同时将资源让给工作线程,这种线程调度称为阻塞;当I/O操作完毕时,操作系统将这个线程的阻塞状态解除,恢复其对cpu的控制权,让其继续执行;这种I/O模式就是通常的同步式I/O,或者阻塞式I/O;

二,异步I/O操作,或者是非阻塞式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采用单线程,非阻塞,事件驱动的编程模式;

三,node.js的事件循环机制
node.js程序由事件循环开始,到事件循环结束,所有的逻辑都是事件的回调函数,因此Node.js始终在事件循环中,程序的入口就是事件循环第一个事件的回调函数,事件的回调函数在执行过程中,可能会发出I/O请求或直接发射(emit)事件,执行完毕后再返回事件循环,事件循环会检查事件队列中有没有未处理的事件,直到程序结束;

模块和包

模块(module)和包(package)
模块通常需要把各个功能拆分,封装,然后组合起来,在浏览器JavaScript中,脚本模块的拆分和组合通常是使用script 标签来实现Node.js提供了require函数来调用其他模块,而且模块是基于文件的,机制十分简单;
其实模块和包没什么大的区别:包可以理解为实现了某个功能模块的集合,用于分布和维护;
模块是node.js应用程序的基本组成部分,文件和模块是一一对应的,也就是说一个node.js文件就是一个模块,这个文件可能是JavaScript代码,json或者c++扩展;例如 var http = require("http");其中http是node.js的一个核心模块,其内部是C++实现的,外部用JavaScript封装,通过require函数获取这个模块,然后才能使用其中的对象;

创建模块
一个文件就是一个模块,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("MGT360124");

myModule.sayHello()

把一个对象封装到模块中;

//singleObject.js
function Hello () {
    var name;
     this.setName = function (thyName) {
         name = thyName;
      };
    this.sayHello = function () {
          console.log("hello " +name);
    };
};

exports.Hello =Hello ;

在其他文件需要通过require("./singleObject.js").Hello获取Hello对象,但是通过module.exports = Hello;

//singleObject.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("./singleObject.js");

实际上,exports本身仅仅是一个普通的空对象{},
我们只需知道三点就知道 exports 和 module.exports 的区别了:
(1)module.exports 初始值为一个空对象 {}
(2)exports 是指向的 module.exports 的引用
(3)require() 返回的是 module.exports 而不是 exports
其实,Module.exports才是真正的接口,exports只不过是它的一个辅助工具。 最终返回给调用的是Module.exports而不是exports。
所有的exports收集到的属性和方法,都赋值给了Module.exports。当然,这有个前提,就是Module.exports本身不具备任何属性和方法。如果,Module.exports已经具备一些属性和方法,那么exports收集来的信息将被忽略。

创建包
包是在模块基础上更深一步的抽象,node.js包类似c++函数库或者Java的类库,他将某个独立的功能封装起来,用于发布,更新,依赖管理和版本控制,node.js根据是CommonJs实现了包的机制;用npm解决包的发布和获取的需求;
node.js 的包就是一个目录,其中有一个JSON的包说明文件package.json。严格符合CommonJS规范的包应该具有:

package.json必须在顶层目录下;
二进制文件应该在bin文件下;
Javascript代码应该在lib目录下;
文档应该在doc目录下;
单元测试在test目录下;

最简单的包就是一个文件夹下只有一个模块文件包通常是一些模块的集合,在模块的基础上提供了更高层的抽象,相当于提供了一些固定接口的函数库,通过制定package.json,我们可以创建更复杂,更完善,更符合规则的包用于发布;

package.json

node.js在调用某个包时,会首先检查包中的package.json文件的main字段,将其作为包的接口模块,如果是package.json或main字段不存在,则会尝试寻找index.js或者index.node作为包的接口。
package.json是CommonJS规定用来描述包的文件,完全符合规范的package.json含有:

name              包的名称,必须是唯一的,由小写英文字母,数字,下划线组成
description       包的简要说明
version           语义化的版本号
keywords          关键字
maintainers       维护者
contributes       贡献者
bugs              提交bug的地址
licenses          许可证组
repositories      仓库托管地址组
dependencies      包的依赖

包管理器npm
npm用于包的发布,传播,依赖控制,npm提供了命令行可以方便下载,安装,升级,删除;也可以发布和维护包;
一,获取一个包

npm   [install/i]     [packagename]

安装在当前目录的node_modules子目录下。

本地模式和全局模式
npm在默认情况下会在http://npmjs.org搜索或下载包,将包安装当前目录的node_modules子目录下。
全局模式用法:

npm [install/i] -g [packagename]

多数时候并不是许多程序都有可能用到它,为了减少多重副本而使用全局模式,本地模式不会注册path环境变量,使用全局模式安装时npm会将包安装到系统目录下,

一般来说,要把一个包作为工程运行时的一部分时,通过本地模式获取,如果要在命令行下使用,则使用全局模式安装;

包的发布
发布之前,需要让包符合npm的规范,npm有一套以CommonJS为基础的包规范;通过使用:

npm init 

交互式问答产生一个符合标准的package.json,步骤是:
(1)先创建一个目录(package)
(2)在这个目录中运行npm init,产生一系列的问题,
(3)最后填完问题,产生一个标准的package.json
其次,还需要一个账号用于今后的维护自己的包,使用:

npm adduser 

根据提示输入 用户名,密码,邮箱,等待创建账号完成后使用:

npm whoami

测试是否已经取得账号
最后是发布包

npm pulish

稍等片刻就发布完成了,打开浏览器,访问http://search.npmjs.org可以找到发布的包,可以通过 npm install package来安装这个包

维护更新包:修改package.json文件中version字段然后在使用:

npm publish

如果对包不满意可以取消发布:

npm unpublish
3人推荐
随时随地看视频
慕课网APP

热门评论

查看全部评论