NodeJs基础一

1、创建Node.js应用
2、NPM使用介绍
3、Node.js REPL(交互式解释器)
4、Node.js 回调函数
5、Node.js 事件循环

介绍
Node.js就是运行在服务器端的JavaScript
Node.js是一个基于Chrome JavaScript运行时建立的一个平台
Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行JavaScript的速度非常快,性能非常好
在使用Node.js时,我们不仅仅在实现一个应用,同时还实现了整个HTTP服务器。

Node.js组成部分

  1. 引入required模块:我们可以使用require指令来载入Node.js模块
  2. 创建服务器:服务器可以监听客户端的请求,类似于Apache、Nginx等HTTP服务器
  3. 接收请求与响应请求:服务器很容易创建,客户端可以使用浏览器或终端发送HTTP请求,服务器接收请求后返回响应数据。

一、创建Node.js应用

1.引入required模块

创建server.js文件,我们使用required指令来载入http模块,并将实例化的HTTP赋值给变量http

1
var http = require('http');

2.创建服务器

接下来我们使用http.createServer()方法创建服务器,并使用listen方法绑定8888端口。函数通过request,response参数来接收和响应数据。
createServer()函数返回一个对象,这个对象有一个叫做listen的方法,这个方法有一个数值参数,指定这个HTTP服务器监听的端口号。

1
2
3
4
5
6
7
8
9
10
11
12
http.createServer(function(request, response){
// 发送HTTP头部
// HTTP状态值:200:OK
// 内容类型:text/plain
response.writeHead(200, {'Content-Type':'text/plain'});

// 发送响应数据“Hello World”
response.end('Hello World\n');
}).listen(8888);

// 终端打印如下信息
console.log('Server running at http://127.0.0.1:8888/');

3.执行代码

1
node server.js

接下来浏览器访问http://127.0.0.1:8888/ 即可看到“Hello World”


二、NPM使用介绍

NPM是随同NodeJS一起安装的包管理工具,能解决NodeJS代码部署上的很多问题。

  • 允许用户从NPM服务器下载别人编写的第三方包到本地使用
  • 允许用户从NPM服务器下载并安装别人编写的命令行程序到本地使用
  • 允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用

查看NPM版本

1
npm -v

升级版本(win),全局安装

1
npm install npm -g

1.使用NPM命令安装模块

1
2
3
4
npm install <Module Name>

// 使用npm命令安装常用的NodeJS Web框架模块express
npm install express

安装好之后,express包就放在工程目录下的node_modules目录中,因此在代码中只需要通过require(‘express’)的方式就好,无需指定第三方包路径。

1
var express = require('express');

2.使用package.json

package.json位于模块的目录下,用于定义包的属性。

  • name:包名字
  • version:包的版本号
  • descriptioin:包的描述
  • homepage:包的官网url
  • author:包的作者姓名
  • contributors:包的其他贡献者姓名
  • dependencies:依赖包列表。如果依赖包没有安装,npm会自动将依赖包安装在node_module目录下
  • repository:包代码存放的地方的类型,可以是git或svn,git可在Github上
  • mian:main字段是一个模块ID,它是一个指向你程序的主要项目。就是说,如果你的包的名字交express,然后用户安装它,然后require(‘express’)。
  • keywords:关键字

3.卸载模块

1
2
3
4
npm uninstall express

// 查看存在的包
npm ls

4.更新模块

1
npm update express

5.搜索模块

1
npm search express

6.创建模块

创建模块,package.json文件是必不可少的。我们可以使用NPM生成package.json文件,生成的文件包含了基本的结果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
C:\Users\DELL\module>npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg> --save` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
name: (module) guosk
version: (1.0.0)
description: NodeJS module test
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to C:\Users\DELL\module\package.json:

// 下面是生成的文件代码

{
"name": "guosk",
"version": "1.0.0",
"description": "NodeJS module test",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}


三、Node.js REPL(交互式解释器)

REPL(Read Eval Print Loop:交互式解释器)表示一个电脑环境,类似Window系统的终端或Unix/Linux shell,我们可以在终端中输入命令,并接收系统的响应。
Node自带了交互式解释器,可以执行以下任务:

  • 读取:读取用户输入,解析输入的JavaScript数据结构并存储在内容中
  • 执行:执行输入的数据结构
  • 打印:输出结果
  • 循环:循环操作以上步骤直到用户两次按下Ctrl+C按钮退出

在终端输入node来启动REPL

1
2
$ node
>

1.简单的表达式运算

1
2
3
$ node
> 1 +4

5

2.使用变量

变量声明需要使用var关键字,如果没有使用var关键字变量会直接打印出来
使用var关键字的变量可以使用console.log()来输出变量

1
2
3
4
5
6
7
8
9
10
$ node
> x = 10
10
> var y = 10
undefined
> x + y
20
> console.log("Hello World")
Hello World
undefined

3.多行表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
$ node
> var x = 0
undefined
> do {
... x++;
... console.log("x: " + x);
... } while ( x < 5 );
x: 1
x: 2
x: 3
x: 4
x: 5
undefined

4.下划线(_)变量

可以使用下划线(_)获取表达式的运算结果

1
2
3
4
5
6
7
8
9
10
11
12
$ node
> var x = 10
undefined
> var y = 20
undefined
> x + y
30
> var sum = _
undefined
> console.log(sum)
30
undefined

5.REPL命令

  • ctrl + c:退出当前终端
  • ctrl + c + c:退出REPL
  • ctrl + d:退出Node REPL
  • 向上/向下键:查看输入的历史命令
  • tab:列出当前命令
  • .help:列出当前命令
  • .break:退出多行表达式
  • .clear:退出多行表达式
  • .save filename:保存当前的Node REPL会话到指定文件
  • .load filename:载入当前Node REPL会话的文件内容

四、Node.js回调函数

Node.js异步编程的直接体现就是回调。回调函数在完成任务后就会被调用,Node使用了大量的回调函数,Node所有API都支持回调函数。
例如,我们可以一遍读取文件,一遍执行其他命令,在文件读取完成后,我们将文件内容作为回调函数的参数返回。这样在执行代码时就没有阻塞或等待文件I/O操作。这就大大提高了Node.js的性能,可以处理大量的并发请求。

阻塞代码实例
创建一个input.txt文件

1
菜鸟教程

创建main.js文件

1
2
3
4
var fs = require("fs");
var data = fs.readFileSync('input.txt');
console.log(data.toString());
console.log("程序执行结束");

执行以上代码

1
2
3
node main.js
菜鸟教程
程序执行结束

非阻塞代码实例
创建一个文件input.txt

1
菜鸟教程

创建一个main.js文件

1
2
3
4
5
6
7
var fs = require('fs');
// 在文件读取后,将文件内容作为回调函数的参数返回。
fs.readFile('input.txt', function(err, data){
if(err) return console.error(err);
console.log(data.toString());
});
console.log("程序执行完毕");

执行以上代码

1
2
3
node main.js
程序执行完毕
菜鸟教程

第一个实例在文件读取完后才执行万程序;第二个实例我们不需要等待文件读取完,这样就可以在读取文件同时执行接下来的代码,大大提高了程序的性能。
因此,阻塞是按顺序执行的,而非阻塞是不按顺序的,所以如果需要处理回调函数的参数,我们就需要写在回调函数内。


五、Node.js事件循环

Node.js是单进程单线程应用程序,但是通过事件和回调支持并发,所以性能非常高。
Node.js的每一个API都是异步的,并作为一个独立线程运行,使用异步函数调用,并处理并发。
Node.js基本上所有的事件机制都是用设计模式中观察者模式实现。
Node.js单线程类似进入一个while的事件循环,知道没有事件观察者退出,每个异步事件都生成一个时间观察者,如果有事件发生就调用该回调函数。

1.事件驱动程序

Node.js使用事件驱动模型,当web server接收到请求,就把它关闭然后进行处理,然后去服务下一个web请求。
当这个请求完成,它被放回处理队列,当到达队列开头,这个结果被返回给用户。
这个模型非常高效可扩展性非常强,因为webserver一直接受请求而不等待任何读写操作。
在事件驱动模型中,会生成一个主循环来监听事件,当检测到事件时触发回调函数。

我们可以通过引入events模块,并通过实例化EventEmitter类来绑定和监听事件

1
2
3
4
// 引入events模块
var events = require('events');
// 创建eventEmitter对象
var eventEmitter = new events.EventEmitter();

程序绑定时间处理程序

1
2
// 绑定事件的处理程序
eventEmitter.on('eventName', eventHandler);

触发事件

1
eventEmitter.emit('eventName');

2.Node应用程序是如何工作的

在Node应用程序中,执行异步操作的函数将回调函数作为最后一个参数,回调函数接收错误对象作为第一个参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 新建input.txt文件
菜鸟教程

// 创建main.js文件
var fs = require('fs');

fs.readFile('input.txt', function(err, data){
if(err){
console.log(err.stack);
return;
}
console.log(data.toString());
});
console.log("程序执行完毕");

以上fs.readFile()是异步函数用于读取文件;如果在读取文件过程中发生错误,错误err对象就会输出错误信息。如果没发生错误,readFile跳过err对象的输出,文件内容就通过回调函数输出。
正确执行结果

1
2
程序执行完毕
菜鸟教程

错误执行结果

1
2
程序执行完毕
Error:ENOENT, open 'input.txt' // 因为文件不存在,所以输出了错误信息