实验楼学习nodejs

来源:互联网 发布:苹果官解网络锁教程 编辑:程序博客网 时间:2024/05/11 19:07

第一节 nodejs课程介绍

一、实验说明:(环境登录、环境介绍、环境使用);

二、nodejs介绍

1.概述

Node.js是基于Chrome JavaScript运行时建立的一个平台,实际上它是对Google Chrome V8引擎进行了封装,它主要用于创建快速的、可扩展的网络应用。Node.js采用事件驱动和非阻塞I/O模型,使其变得轻量和高效,非常适合构建运行在分布式设备的数据密集型的实时应用。

运行于浏览器的JavaScript,浏览器就是JavaScript代码的解析器,而Node.js则是服务器端JavaScript的代码解析器,存在于服务器端的JavaScript代码由Node.js来解析和运行。

JavaScript解析器只是JavaScript代码运行的一种环境,浏览器是JavaScript运行的一种环境,浏览器为JavaScript提供了操作DOM对象和window对象等的接口。Node.js也是JavaScript运行的一种环境,Node.js为JavaScript提供了操作文件、创建HTTP服务、 创建TCP/UDP服务等的接口,所以Node.js可以完成其他后台语言(Python、PHP等)能完成的工作。

2.交互式运行环境

Node.js提供了一个交互式运行环境,通过这个环境,可以立即执行JavaScript代码块,使用方法类似于Chrome浏览器中Firebug插件的Console。

三、nodejs模块和包

1.模块

Node.js官方提供了很多模块,这些模块分别实现了一种功能,如操作文件的模块fs,构建http服务的模块http等,每个模块都是一个JavaScript文件,当然也可以自己编写模块。

2.包

包可以将多个具有依赖关系的模块组织在一起,封装多个模块,以方便管理。Node.js采用了CommonJS规范,根据CommonJS规范规定,一个JavaScript文件就是一个模块,而包是一个文件夹,包内必须包含一个JSON文件,命名为package.json。一般情况下,包内的bin文件夹存放二进制文件,包内的lib文件夹存放JavaScript文件,包内的doc文件夹存放文档,包内的test文件夹存放单元测试。package.json文件中需要包含的字段及包的使用等。

3.npm包管理工具

npm是Node.js的包管理工具,npm定义了包依赖关系标准,我们使用npm主要用来下载第三方包和管理本地下载的第三方包。

第二节 nodejs模块

一、nodejs模块

每一个 Node.js 文件都是一个 Node.js 模块,包括JavaScript文件(.js)、JSON文本文件(.json)和二进制模块文件(.node)。

1.模块的使用

(1)新建一个JS文件,写入内容,就是一个nodejs模块,但是怎么在其他模块中引入并使用这个模块呢?我们需要为模块提供对外的接口,这就要用到module.exports和exports。
(2)在其他模块中,可以使用require(module_name);载入需要的模块。

2.moduls.exports和exports

module是一个对象,每个模块中都有一个module对象,module是当前模块的一个引用。module.exports对象是Module系统创建的,而exports可以看作是对module.exports对象的一个引用。在模块中require另一个模块时,以module.exports的值为准,因为有的情况下,module.exports和exports它们的值是不同的。

二、nodejs包

1.包

  • 包用于管理多个模块及其依赖关系,可以对多个模块进行封装,包的根目录必须包含package.json文件,package.json文件是CommonJS规范用于描述包的文件,符合CommonJS规范的package.json文件应该包含以下字段:
    • name:包名。包名是唯一的,只能包含小写字母、数字和下划线。
    • version:包版本号。
    • description:包说明。
    • keywords:关键字数组。用于搜索。
    • homepage:项目主页。
    • bugs:提交bug的地址。
    • license:许可证。
    • maintainers:维护者数组。
    • contributors:贡献者数组。
    • repositories:项目仓库托管地址数组。
    • dependencies:包依赖。

2.npm包管理工具

  • 由于实验楼环境网络限制,所以npm命令会连接taobao的源,而不会直接连接官方源。
    (1)搜索包:npm search *
    (2)安装包:npm install *
    (3)更新包:npm update *
    (4)卸载包:npm uninstall *

第三节 nodejs events模块

1.简介

在Node.js中,很多对象都会发出事件。比如,fs.readStream打开文件时会发出一个事件。所有发出事件的对象都是events.EventEmitter的实例,可以通过require(“events”);获得event模块。

通常,事件名采用“驼峰式”命名方式,但是,并没有严格规定。这只是推荐的命名方法。

函数可以添加给对象,对象发出事件时,对应函数就会被执行。这些函数被称作监听器(listeners)。在监听器函数中,this引用的是它(指此监听器函数)添加到的EventEmitter对象。

2.class:events.EventEmitter

通过require(‘events’).EventEmitter得到EventEmitter类。

当EventEmitter对象遇到错误时,通常会触发error事件。error事件在Node.js中是一种特殊情况,如果没有监听器,那么默认会打印出栈跟踪器并退出程序。

3.添加监听器

为事件绑定事件处理程序,可以使用emitter.addListener(event, listener)和emitter.on(event, listener),它们的作用是完全一样的。传入的参数是事件(event)和处理函数(listener)。

4.只执行一次的监听器

使用emitter.once(event, listener)绑定的事件监听器只会执行一次,然后就会被删除掉。

5.移除监听器

移除监听器使用emitter.removeListener(event, listener)。

6.移除所有监听器

移除所有监听器使用emitter.removeAllListeners([event])。

7.设置监听器最大绑定书

emitter.setMaxListeners(n)可以设置同一事件的监听器最大绑定数,默认情况下,超过10个就会警告提示,这能帮我们快速找到类存泄露的地方。显然,不是所有的事件触发器都限制在10个监听器,通过这个方法可以设置,如果设置为0就是无限制。

8.自定义事件

使用emitter.emit(event, [arg1], [arg2], […])可以触发自定义的事件。

9.查看事件绑定的监听器个数

使用EventEmitter.listenerCount(emitter, event)可以查看事件监听器数量。

第四节 nodejs fs模块

  • fs模块用于对系统文件及目标进行读写操作

一、同步和异步

使用require(‘fs’)载入fs模块,模块中所有方法都有同步和异步两种形式。

异步方法中回调函数的第一个参数总是留给异常参数(exception),如果方法成功完成,那么这个参数为null或者undefined。

同步方法执行完并返回结果后,才能执行后续的代码。而异步方法采用回调函数接收返回结果,可以立即执行后续的代码。

fs中unlink\unlinkSync(异步、同步删除文件)方法;

二、readFile读取文件

使用fs.readFile(filename, [options], callback)方法读取文件。

readFile接收三个参数,filename是文件名;[options]是可选的参数,为一个对象,用于指定文件编码(encoding)及操作方式(flag);callback是回调函数。

readFile的回调函数接收两个参数,err是读取文件出错时触发的错误对象,data是从文件读取的数据。

data数据是原始二进制数据在缓冲区中的内容。要显示文件内容可以使用toString()或者设置输出编码(utf-8);

fs.readFileSync(filename, [options])是readFile的同步方法。

三、writeFile写入文件

使用fs.writeFile(filename, data, [options], callback)写入内容到文件。

writeFile接收四个参数,filename是文件名称;data是要写入文件的数据;[options]是一个对象为可选参数,包含编码格式(encoding),模式(mode)以及操作方式(flag);callback是回调函数。

写入文件内容(如果文件不存在会创建一个文件),写入时会先清空文件,还可以传递了追加参数 { ‘flag’: ‘a’ }(避免清空);
flag传递的值,r代表读取文件,,w代表写入文件,a代表追加写入文件,还有其他的值不作详细介绍。

四、使用fs.read和fs.write读写文件

使用fs.read和fs.write读写文件需要使用fs.open打开文件和fs.close关闭文件。

1.fs.read()

先介绍fs.open(path, flags, [mode], callback)方法,此方法用于打开文件,以便fs.read()读取。path是文件路径,flags是打开文件的方式,[mode]是文件的权限(可选参数,默认值是0666),callback是回调函数。

  • flags的值:
    • r :读取文件,文件不存在时报错;
    • r+ :读取并写入文件,文件不存在时报错;
    • rs :以同步方式读取文件,文件不存在时报错;
    • rs+ :以同步方式读取并写入文件,文件不存在时报错;
    • w :写入文件,文件不存在则创建,存在则清空;
    • wx :和w一样,但是文件存在时会报错;
    • w+ :读取并写入文件,文件不存在则创建,存在则清空;
    • wx+ :和w+一样,但是文件存在时会报错;
    • a :以追加方式写入文件,文件不存在则创建;
    • ax :和a一样,但是文件存在时会报错;
    • a+ :读取并追加写入文件,文件不存在则创建;
    • ax+ :和a+一样,但是文件存在时会报错。

fs.close(fd, [callback])用于关闭文件,fd是所打开文件的文件描述符。

fs.read(fd, buffer, offset, length, position, callback)方法接收6个参数。

  • fd是文件描述符,必须接收fs.open()方法中的回调函数返回的第二个参数;
  • buffer是存放读取到的数据的Buffer对象;
  • offset指定向buffer中存放数据的起始位置;
  • length指定读取文件中数据的字节数;
  • position指定在文件中读取文件内容的起始位置;
  • callback是回调函数,回调函数的参数:
    • err用于抛出异常;
    • bytesRead是从文件中读取内容的实际字节数;
    • buffer是被读取的缓存区对象。
var fs = require('fs'); // 引入fs模块// 打开文件fs.open('./testread.txt', 'r', function(err, fd) {    if (err) {        throw err;    }    console.log('open file success.');    var buffer = new Buffer(255);    // 读取文件    fs.read(fd, buffer, 0, 10, 0, function(err, bytesRead, buffer) {        if (err) {            throw err;        }        // 打印出buffer中存入的数据        console.log(bytesRead, buffer.slice(0, bytesRead).toString());        // 关闭文件        fs.close(fd);    });});

fs.write()

fs.write(fd, buffer, offset, length, position, callback)方法的参数和fs.read()相同,buffer是需要写入文件的内容。

五、目录操作

1.创建目录

使用fs.mkdir(path, [mode], callback)创建目录,path是需要创建的目录,[mode]是目录的权限(默认值是0777),callback 是回调函数。

删除目录可以使用fs.rmdir(path, callback),但是只能删除空目录。

2.读取目录

使用fs.readdir(path, callback)读取文件目录。

var fs = require('fs'); // 引入fs模块fs.readdir('./newdir', function(err, files) {    if (err) {        throw err;    }    // files是一个数组    // 每个元素是此目录下的文件或文件夹的名称    console.log(files);});

第五节 nodejs的http模块

  • http模块主要用于创建http server服务,还会讲到url模块和path模块,同时也会用到前面讲过的fs模块。url模块用于解析url,path模块用于处理和转换文件路径。

一、创建http server(起一个web服务器,监听请求)

二、创建路由(根据不同的请求,调用不同的handle<处理函数>)

三、创建主程序(把router、handler作为参数启动web服务器,做到低耦合)

四、创建HTML文件(根据不同的请求,显示不同的内容)

第六节 nodejs中的网络编程

  • 主要讲解TCP和UDP的网络编程,net模块提供了一个异步网络包装器,用于TCP网络编程,它包含了创建服务器和客户端的方法。dgram模块用于UDP网络编程。

TCP Server

  • net模块通过net.createServer方法创建TCP服务器,通过net.connect方法创建客户端去连接服务器。
  • process是一个Node.js的全局模块,可以在任何地方直接使用而无需通过require方法引入。process模块允许你获得或者修改当前Node.js进程的设置。process.stdin用于获取来自标准输入的可读流(Readable Stream)。
  • 监听服务消息有:data,end,connection,error,close等;

UDP Server

  • UDP和TCP类似,通过dgram.createSocket创建服务。
  • 发送的消息必须通过Buffer创建。
  • 监听服务消息有:error,message,listening等;

第七节 nodejs中的进程

  • 主要学习Node.js中的进程,涉及的模块是Cluster、Porcess和child_process。

process模块

process使用时直接通过全局变量process访问,而不需要通过require方法加载。process用来和当前Node.js程序进程互动。

process是EventEmitter的一个实例,process主要包含退出事件、信号事件以及一些属性。

退出事件(exit)

当退出当前进程时,会促发exit事件,exit事件的回调函数中只接受同步操作,并且回调函数只接受一个参数,即退出代码,如:

process.on('exit', function(code) {    setTimeout(function() {        console.log('This will not run');    }, 0);    console.log('exit code: ', code);});

运行上面的代码,其中setTimeout方法中的回调函数是不会被执行的,因为exit事件中只会运行同步操作,而不会运行异步操作。

在exit事件之前还有一个beforeExit事件会被触发,在beforeExit的回调函数中可以执行异步操作。值得注意的是,通过process.exit()退出程序或者因为发生错误而退出程序是不会触发beforeExit事件的。顺便说一下,当有错误未被捕获时,就会触发uncaughtException事件。

信号事件

信号事件就是接收到某个特定信号才会被触发的事件。

比如SIGINT事件的触发方式是ctrl+c:

process.stdin.resume();process.on('SIGINT', function() {    console.log('Got SIGINT.  Press Control-D to exit.');});

运行代码,然后按住control键,再按C键就会触发SIGINT事件。

属性

process模块提供了很多属性,其中关于IO输入输出的主要有三个:

  • process.stdin // 标准输入
  • process.stdout // 标准输出
  • process.stderr // 标准错误
例子:// stdin.jsprocess.stdin.setEncoding('utf8');process.stdin.on('readable', function() {    var chunk = process.stdin.read();    if (chunk !== null) {        process.stdout.write('data: ' + chunk);    }});process.stdin.on('end', function() {    process.stdout.write('end');});

运行,输入任意字符,Node.js会把输入的字符打印出来,输入ctrl+D触发end事件。

还有其他属性,比如process.argv是一个包含了命令行参数的数组。

方法

process模块还有很多实用的方法,比如:

  • process.cwd() // 返回脚本运行工作目录
  • process.chdir() // 切换工作目录
  • process.exit() // 退出当前进程
  • process.on() // 添加监听事件
    //…

child_process模块

child_process用于创建子进程。

child_process.spawn()方法

通过当前命令启动一个新的进程。如:

// test_spawn.jsvar spawn = require('child_process').spawn,    ls    = spawn('ls', ['-lh', '/usr']);ls.stdout.on('data', function (data) {    console.log('stdout: ' + data);});ls.stderr.on('data', function (data) {    console.log('stderr: ' + data);});ls.on('close', function (code) {    console.log('child process exited with code ' + code);});

运行,从结果可以看出,子进程成功运行了ls -lh /usr命令。

child_process.exec()方法

child_process.execFile()方法

  • 与exec方法类似,执行特定程序文件,参数通过一个数组传送。

child_process.fork()方法

直接创建一个子进程,此进程是node命令的子进程,fork(‘./sub.js’)相当于spwan(‘node’, ‘./sub.js’)。fork还会在父进程与子进程之间,建立一个通信管道,通过child.send()发送消息。

cluster模块

单个的Node实例运行在单个线程中。要发挥多核系统的能力,需要启动一个Node进程集群来处理负载。cluster模块就用于创建共享服务器端口的子进程。

// test_cluster.jsvar cluster = require('cluster');var http = require('http');var numCPUs = require('os').cpus().length;  // 获取CPU内核数// master是主进程// 此处判断是否为master进程// 是则根据CPU内核数创建worker进程if (cluster.isMaster) {    // worker是运行节点    // 根据CPU数量启动worker    // Fork workers    for (var i = 0; i 
0 0
原创粉丝点击