http模块:配置简单 的web服务,npm/cnpm工具javascript
express框架:express中间件进行服务配置;路由;请求处理;html
DB服务:学习使用mysql关系型数据库;java
web接口服务:使用express、koa简单配置接口服务、JSON解析;node
nodejs RESTful API:提供跨语言、跨平台的服务接口、支持web/appmysql
node文件系统:服务端基本的文件读写操做nginx
Node.js是一个让JavaScript运行在服务器端的开发平台,它让JavaScript的触角伸到了服务器端。但Node.js彷佛与其它服务器端语言有点不一样:web
Node.js不是一种独立的语言,与PHP、Python等“既是语言,又是平台”不一样,Node.js使用的是JavaScript进行编程,Node.js是一个工具,语言还是JavaScript。sql
与PHP、JSP等相比,Node.js跳过了apache、tomcat、nginx、iis等http服务器,它本身不用创建在任何服务器软件之上。数据库
Node.js哲学:花最小的硬件成本,追求更高的并发,更高的处理性能。express
Node采用一系列“非阻塞”库来支持事件循环的方式。本质上就是为文件系统、数据库之类的资源提供接口。向文件系统发送一个请求时,无需等待硬盘(寻址并检索文件),硬盘准备好的时候非阻塞接口会通知Node。该模型以可扩展的方式简化了对慢资源的访问, 直观,易懂。尤为是对于熟悉onmouseover、onclick等DOM事件的用户,更有一种似曾相识的感受。
单线程:
说明Node.js是单线程的一个实例 :
Node.js能够在不新增额外线程的状况下,依然能够对任务进行并发处理 —— Node.js是单线程的。它经过事件循环(event loop)来实现并发操做,对此,咱们应该要充分利用这一点 —— 尽量的避免阻塞操做,取而代之,多使用非阻塞操做。
事件驱动:
异步回调:至关于一个服务员照顾多个顾客
说明实例:当有多个用户同时访问的时候,会出现同一个用户进来和读取完毕不连续的状况
只要I/O越多,Node.js宏观上越并行;但运算越多,Node.js宏观上越不并行,此时网页打开速度严重变慢,由于计算过程当中CPU只能为某一用户服务,难以脱身,因此Node.js线程就被这一用户霸占了。
所以Node.js适合开发I/O多的业务,而不适合计算任务繁重的业务。
非阻塞I/O:
例如:当访问数据库取得数据的时候,须要一段较长的时间,在传统的处理机制中,在执行了访问数据库代码以后,整个线程都将暂停下来等待数据库返回结果才能执行后面的代码,也就是说I/O阻塞了后面代码的执行,极大的下降了程序的执行效率。
因为Node.js采用了非阻塞I/O机制,所以在执行了访问数据库的代码以后,将当即转而执行其后面的代码,将数据库返回结果的处理代码放在回调函数中,从而提升了程序的执行效率。
当某个I/O执行完毕时,将以事件的形式通知执行I/O操做的线程,线程执行这个事件的回调函数。为了处理异步I/O,线程必须有事件循环,不断的检查有没有未处理的事件,依次予以处理。
在阻塞模式下,一个线程只能处理一项任务,要想提升吞吐量必须经过多线程。而非阻塞模式下,一个线程永远在执行计算操做,这个线程的核心利用率永远是100%,因此这个是一个特别有哲理的解决方案:与其人多,但好多人闲着,还不如一我的玩命,往死里干活。
Node..js适合开发的业务:
当业务程序须要处理大量并发的I/O,而在向客户端发出响应以前,应用程序内部并不须要进行很是复杂的处理的时候,Node..js很是合适。Node..js也很是适合和websocket配合,开发长链接的实时交互应用程序,好比:用户表单收集、考试系统、聊天室、图文直播、提供JSON的API(为MVVM框架使用)。
一、经常使用的命令:
dir:列出当前文件夹下的全部文件;
cd 目录名:进入到指定的目录;
md 目录名:建立一个指定的文件夹;
rd 目录名:删除一个指定的文件夹;
二、目录:
.:表示当前目录;
..:表示上一级目录;
三、环境变量:
path:当咱们在命令行窗口打开一个文件或调用一个程序时系统会首先在当前目录下寻找程序,若是找到了则直接打开,若是没有找到则会依次到环境变量path的路径中寻找,直到找到为止,若是没有找到则会报错。
四、快速进入指定文件夹的方法:
在指定文件夹的地址栏中输入:cmd
进程:负责为程序的运行提供必备的环境,至关于工厂中的车间;
线程:计算机中最小的计算单元,负责执行进程中的程序,至关于工厂中的工人。
cmd中进入hello.js所在文件夹,cmd中输入:
WebStorm菜单的File->Settings:搜索node,找到Node.js and NPM,在右侧的Node interpreter中输入node.exe所在位置便可。
WebStorm菜单的File->Settings:搜索node,找到Node.js and NPM,在右侧的Coding Assistance中启用便可。
在Node中,一个js文件就是一个模块;
在 Node中,每个js文件的js代码都是独立运行在一个函数中,好比:
实际上是:
而不是全局做用域,因此一个模块中的变量和函数在其它模块中没法访问 。
在Node中,经过require()函数来引入外部模块,require()中能够传递一个文件的路径做为参数,node将会自动根据该路径来引入外部模块,这里路径若是使用相对路径,则必须以“.”或者“..”开头;
咱们能够经过exports来向外部暴露变量或者方法,只须要将须要暴露给外部的变量或者方法设置为exprots的属性便可。
使用require()引入模块之后,该函数会返回一个对象,这个对象表明的是引入的模块。
咱们使用require()引入外部模块时,使用的就是模块标识。
模块分红两大类:
核心模块:由node引擎提供的模块,核心模块的标识就是模块的名字;
文件模块:用户自定义的模块,文件模块的标识就是文件的路径。
node模块中用var定义的变量都是局部变量,取消掉var时定义的变量才是所有变量:
输出:
由此可知:
当node在执行模块中的代码时,它首先会在代码的最顶部添加以下代码:
在代码的最底部,添加以下代码:
实际上,模块中的代码都是包装在一个函数中执行的,而且在函数执行时,同时传递了5个实参:
exports:该对象用来将对象或者函数暴露到外部,
require:函数,用来引入外部的模块,
module:用来表明的是当前模块自己,exports就是模块的属性。既能够用exports导出,也能够用module.exports导出二者指向的是同一个对象,
__filename:当前模块的完整路径,
__dirname:当前模块所在文件夹的完整路径
本质上二者是相等的,可是exports只能经过“.”的方式向外暴露内部变量,而modules.exports既能够经过“.”的形式,也能够直接赋值;
CommonJS的包规范容许咱们将相关的模块组合在一块儿,造成一组完整的工具。
CommonJS的包规范包括包结构和包描述文件。
包结构:
package.json:必须
bin:可执行的二进制文件,非必须
lib:js文件,非必须;
doc:文档,非必须;
test:单元测试,非必须
包描述文件:
用于表达非代码相关的信息,它是一个json文件-package.json,位于包的根目录下,是包的重要组成部分。
至关于360安全卫士里的软件管家。
对于node而言,npm帮助其完成了第三方模块的发布、安装和依赖等。借助npm,node与第三方模块之间造成了很好的一个生态系统。
npm -v:查看npm版本;
npm version: 查看全部模块的版本;
npm search 包名:搜索包;
npm install/i 包名 :安装包;
npm remove/r 包名:删除包;
npm remove/r 包名 --save:将包名在依赖中删除(node _modules中不删除);
npm install 包名 --save:安装包并添加到依赖中(package.json的dependencies中);
npm install:下载当前项目所依赖的包(package.json的dependencies中的包);
npm install 包名 -g:全局安装包(全局安装的包通常是一些工具)
经过npm下载的包都放到node_modules中,咱们经过npm下载的包直接经过包名引用便可。
node在经过模块名字来引用模块时它会首先在当前目录的node_modules中寻找是否含有该模块,若是有则直接使用,若是没有则直接去上一级目录的node_modules中寻找,若是有则直接使用,若是没有,则继续再去上一级目录中寻找,直到找到磁盘的根目录,若是依然没有,则直接报错。
Node.js 全部的异步 I/O 操做在完成时都会发送一个事件到事件队列。
Node.js 里面的许多对象都会分发事件:一个 net.Server 对象会在每次有新链接时触发一个事件, 一个 fs.readStream 对象会在文件被打开的时候触发一个事件。 全部这些产生事件的对象都是 events.EventEmitter 的实例。
events 模块只提供了一个对象: events.EventEmitter。EventEmitter 的核心就是事件触发与事件监听器功能的封装。
你能够经过require("events");来访问该模块。
EventEmitter 对象若是在实例化时发生错误,会触发 error 事件。当添加新的监听器时,newListener 事件会触发,当监听器被移除时,removeListener 事件被触发。
下面咱们用一个简单的例子说明 EventEmitter 的用法:
执行结果以下:
运行这段代码,1 秒后控制台输出了 'some_event 事件触发'。其原理是 event 对象注册了事件 some_event 的一个监听器,而后咱们经过 setTimeout 在 1000 毫秒之后向 event 对象发送事件 some_event,此时会调用some_event 的监听器。
EventEmitter 的每一个事件由一个事件名和若干个参数组成,事件名是一个字符串,一般表达必定的语义。对于每一个事件,EventEmitter 支持 若干个事件监听器。
当事件触发时,注册到这个事件的事件监听器被依次调用,事件参数做为回调函数参数传递。
让咱们如下面的例子解释这个过程:
执行以上代码,运行的结果以下:
以上例子中,emitter 为事件 someEvent 注册了两个事件监听器,而后触发了 someEvent 事件。
运行结果中能够看到两个事件监听器回调函数被前后调用。 这就是EventEmitter最简单的用法。
EventEmitter 提供了多个属性,如 on 和 emit。on 函数用于绑定事件函数,emit 属性用于触发一个事件。接下来咱们来具体看下 EventEmitter 的属性介绍。
方法
序号 | 方法 & 描述 |
---|---|
1 | addListener(event, listener) 为指定事件添加一个监听器到监听器数组的尾部。 |
2 | on(event, listener) 为指定事件注册一个监听器,接受一个字符串 event 和一个回调函数。 |
3 | once(event, listener) 为指定事件注册一个单次监听器,即 监听器最多只会触发一次,触发后马上解除该监听器。 |
4 | removeListener(event, listener) 移除指定事件的某个监听器,监听器必须是该事件已经注册过的监听器。 它接受两个参数,第一个是事件名称,第二个是回调函数名称。 |
5 | removeAllListeners([event]) 移除全部事件的全部监听器, 若是指定事件,则移除指定事件的全部监听器。 |
6 | setMaxListeners(n) 默认状况下, EventEmitters 若是你添加的监听器超过 10 个就会输出警告信息。 setMaxListeners 函数用于提升监听器的默认限制的数量。 |
7 | listeners(event) 返回指定事件的监听器数组。 |
8 | emit(event, [arg1], [arg2], [...]) 按参数的顺序执行每一个监听器,若是事件有注册监听返回 true,不然返回 false。 |
类方法
序号 | 方法 & 描述 |
---|---|
1 | listenerCount(emitter, event) 返回指定事件的监听器数量。 |
事件
序号 | 事件 & 描述 |
---|---|
1 | newListener
该事件在添加新监听器时被触发。 |
2 | removeListener
从指定监听器数组中删除一个监听器。须要注意的是,此操做将会改变处于被删监听器以后的那些监听器的索引。 |
实例
如下实例经过 connection(链接)事件演示了 EventEmitter 类的应用。
建立 main.js 文件,代码以下:
以上代码,执行结果以下所示:
server.js
handler.js
index.html
Buffer的结构和数组很像,操做的方法也和数组相似;
数组中不能存储二进制的文件,而Buffer就是专门用来存储二进制数据;
为何要用Buffer?Node.js其实就作两件事,一是接收请求,另外一个是发送请求,请求都是以二进制的方式传递的,接收之后或者发送以前二进制数据都是放在缓存中。
使用Buffer不须要引用模块,直接使用便可;
在Buffer中存储的是二进制数据,但在显示时是以十六进制的形式显示;存入时的数字能够是任何进制,但在控制台或者页面就是必定只能以十进制输出显示,若是存储的是字符的话能够用其它进制显示,方式str.toString(x);
Buffer中每个元素的范围是00-ff(16进制) <=> 0-255(10进制) <=> 00000000-11111111(2进制);
计算机中1个0或者1个1咱们称之为1位(bit),计算机中数据是以字节为单位传输的;
8bit=1byte(1字节);
1024byte=1kb;
1024kb=1mb;
1024mb=1gb;
1024gb=1tb;
Buffer中的1个元素占用内存的1个字节;
Buffer的大小一旦肯定,则不能修改,Buffer其实是对底层内存的直接操做;
server.js
review.html
404.html
重构路由代码:
app.js
server.js
router.js
handler.js
文件系统简单来讲就是经过Node.js来操做系统中的文件;
使用文件系统首先须要引入fs模块,fs是核心模块,直接引入不须要下载;
文件的写入步骤:
手动步骤:
a、打开文件;
b、向文件中写入内容;
c、保存并关闭文件;
一、同步写入文件:
二、异步写入文件:
三、简单文件写入(不须要打开文件):
Flag | 描述 |
---|---|
r | 以读取模式打开文件。若是文件不存在抛出异常。 |
r+ | 以读写模式打开文件。若是文件不存在抛出异常。 |
rs | 以同步的方式读取文件。 |
rs+ | 以同步的方式读取和写入文件。 |
w | 以写入模式打开文件,若是文件不存在则建立。 |
wx | 相似 'w',可是若是文件路径存在,则文件写入失败。 |
w+ | 以读写模式打开文件,若是文件不存在则建立。 |
wx+ | 相似 'w+', 可是若是文件路径存在,则文件读写失败。 |
a | 以追加模式打开文件,若是文件不存在则建立。 |
ax | 相似 'a', 可是若是文件路径存在,则文件追加失败。 |
a+ | 以读取追加模式打开文件,若是文件不存在则建立。 |
ax+ | 相似 'a+', 可是若是文件路径存在,则文件读取追加失败。 |
四、使用绝对路径写入文件:
五、流式文件写入:
同步、异步、简单文件的写入都不太适合大文件的写入,性能较差,容易致使内存溢出。
五、简单文件读取:
六、流式文件读取:
七、fs其它操做:
• 验证路径是否存在
– fs.existsSync(path)
• 获取文件信息
– fs.stat(path, callback)
– fs.statSync(path)
• 删除文件
– fs.unlink(path, callback)
– fs.unlinkSync(path)
列出文件
– fs.readdir(path[, options], callback)
– fs.readdirSync(path[, options])
• 截断文件
– fs.truncate(path, len, callback)
– fs.truncateSync(path, len)
• 创建目录
– fs.mkdir(path[, mode], callback)
– fs.mkdirSync(path[, mode])
删除目录
– fs.rmdir(path, callback)
– fs.rmdirSync(path)
• 重命名文件和目录
– fs.rename(oldPath, newPath, callback)
– fs.renameSync(oldPath, newPath)
• 监视文件更改写入
– fs.watchFile(filename[, options], listener)
响应 json:
响应HTML页面 :
main.js:
index.html:
一、什么是express?
express是也一个基于node.js的极简、灵活的web开发框架。能够实现很是强大的web服务器功能。
二、express的特色:
能够设置中间件响应或过滤http请求;
可使用路由实现动态网页,响应不一样的http请求;
内置支持ejs模板(默认是jade模板)实现模板渲染生成html;
三、express-generator生成器:
express-generator是express官方团队为开发者准备的一个快速生成工具,能够很是快速的生成一个基本的express开发框架。
四、express安装与使用:
1)安装express-generator生成器;
安装完成后可使用express命令。
2)建立项目:
3)安装依赖:
4)开启项目
5)测试项目:
打开浏览器输入localhost
安装驱动:
注意:cnpm install mysql是安装nodejs的mysql模块而不是安装mysql数据库,你的应用经过这个驱动程序链接并操做mysql中的库和表。
若是你的电脑中没有mysql,则请先安装,相关教程以下:
https://jingyan.baidu.com/article/363872ec2e27076e4ba16fc3.html
在进行数据库操做前,你须要将如下SQL 文件导入到你的 MySQL 数据库中。
查询数据
将上面咱们提供的 SQL 文件导入数据库后,执行如下代码便可查询出数据:
插入数据
更新数据
删除数据
nodemon: