了解Node应用方法

目录

1.Node.js简介

什么是Node.js ?

Node.js的应用场景

2.创建第一个应用

2.1引用required模块

2.2创建服务器

2.3接收请求与响应请求

3.模块系统

3.1创建模块

4.url模块

4.1引用

4.2解析

4.3URl模块提供的方法

4.3.1url.parse()

5.路由

6.回调函数

6.1阻塞代码实例

6.2非阻塞代码实例

7.事件循环

7.1事件驱动程序

7.2实例


1.Node.js简介

什么是Node.js ?

        Node.js 是运行在服务端的JavaScript。

        Node.js是一个基于Chrome JavaScript运行时建立的一个平台。

        Node.js是一个事件驱动V/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。

Node.js的应用场景

        Node.js 的具体场景可以表现为如下: ​ 用户表单收集系统、后台管理系统、实时交互系统、考试系统、联网软件、高并发量的web应用程序。

2.创建第一个应用

2.1引用required模块

        在项目的根目录下创建一个叫server.js的文件

我们使用require指令来引入 http模块,并将实例化的HTTP赋值给变量http,实例如下:

var http = require 'http'

2.2创建服务器

        接下来我们使用http.createServer()方法创建服务器,并使用listen方法绑定8888端口。函数通过request、response参数来接收和响应数据。 实例如下:

//创建服务器
http.createServer(function(reuest,response){
}).listen(8888);
//终端打印启动信息
console.log('Server running at http://127.0.0.1:8888/')

2.3接收请求与响应请求

//创建服务器
http.createServer(function(reuest,response){
    //发送HTTP头部
    //HTTP状态值:200(ok)
    response.writeHead(200,{'Content-Type':"text/plain"})
    //发送响应数据"Hello World"
    response.weite("Hello World")
}).listen(8888);
//终端打印启动信息
console.log('Server running at http://127.0.0.1:8888/')

3.模块系统

为了让Node.js 的文件可以相互调用,Node.js 提供了一个简单的模块系统。

        模块是Node.js 应用程序的基本组成部分,文件和模块是一一对应的。换言之,一个Node.js 文件就是一个模块,这个文件可能是JavaScript代码、JSON 或者编译过的C/C++扩展。

3.1创建模块

在Node.js 中,创建一个模块非常简单,如下我们创建一个"hello.js”文件,代码如下:

// 创建模块
exports.world = function() {
    console.log('Hello World');
}
​
//另一种方式
function Hello() {
    let name;
    this.setName = function(theName) {
        name = theName;
    }
    this.sayHello = function() {
        console.log(`Hello ${name}`);
    }
}
module.exports = Hello

        Node.js提供了exports和require两个对象,其中exports,是模块公开的接口,require用于从外部获取一个模块的接口,即所获取模块的exports对象。

接下来我们创建“main.js”文件,代码如下:

var hello = require("./hello");
​
hello.world();
​
​
//另一种方式的接收
var Hello = require('./hello');
​
const hello = new Hello()
hello.setName("薛之谦");
hello.sayHello()

代码require( ' ./hello')引入了当前目录下的hello.js 文件(./为当前目录,node.js默认后缀为js)。

        在以上示例中,hello.js 通过exports对象把 world作为模块的访问接口,在main,js中通过require(./hello')加载这个模块,然后就可以直接访问hello.js 中exports对象的成员函数了。

结果:

4.url模块

4.1引用

Node.js 的URL模块提供了用于分析和解析URL的实用程序。可以调用require('url')来访问它:

const url = require('url');

4.2解析

        解析URL对象有以下内容,依赖于它们是否在URl字符串里存在。任何不在URL字符串里的部分,都不会出现在解析对象里

实例:

var url = require('url');
​
const reqUrl = 'http://user:pass@host.com:8080/p/a/t/h?query=string#hash';
const urlObj = url.parse(reqUrl);
​
// 获取当前url的端口
console.log(urlObj.port);
​
// 获取主机
console.log(urlObj.host);
​
// 获取查询参数
console.log(urlObj.query);
​
const urlObj2 = url.parse(reqUrl, true)
console.log(urlObj2.query);

4.3URl模块提供的方法

4.3.1url.parse()

url.parse(urlStr[,parseQueryString] [,slashesDenoteHost]):输入URL字符串,返回一个对象

第二个参数为true时,使用querystring来解析查询字符串。如果为true,query属性将会一直赋值为对象,并且search属性将会一直是字符串(可能为空)。默认为false。

实例:

const reqUrl = 'http://user:pass@host.com:8080/p/a/t/h?query=string#hash';
const urlObj = url.parse(reqUrl);
// 获取查询参数
console.log(urlObj.query);
​
const urlObj2 = url.parse(reqUrl, true)
console.log(urlObj2.query);

第三个参数为true,把//foo/bar当做{host:'foo',pathname:'/bar'},而不是{pathnameL;//foo/bar'}.默认为false

实例:

const reqUrl = "//foo/bar";
​
const urlObj = url.parse(reqUrl, false);
console.log(urlObj.host, urlObj.pathname);
​
const urlObj2 = url.parse(reqUrl, false, true);
console.log(urlObj2.host, urlObj2.pathname);

5.路由

        我们要为路由提供请求的URL和其他需要的GET及POST参数,随后路由需要根据这些数据来执行相应的代码。

        因此,我们需要查看HTTP请求,从中提取出请求的URL以及GET/POST参数。

        我们需要的所有数据都会包含在request 对象中,该对象作为onRequest)回调函数的第一个参数传递。但是为了解析这些数据,我们需要额外的NodeJS模块,它们分别是url和querystring模块。

        现在,我们来给onRequest()函数加上一些逻辑,用来找出浏览器请求的URL路径。server.js文件代码如下:

var url = require("url");
var http = require("http");
​
function start(route) {
    function OnRequest(request, response) {
        let pathname = url.parse(request.url).pathname;
        console.log(`接收到${pathname}的请求`);
​
        route(pathname);
​
        response.writeHead(200, { 'Content-Type': "text/plain" });
        response.write("Hello Node.js");
        response.end()
    }
    http.createServer(OnRequest).listen(8888)
    console.log("服务器已经启动......访问:http://127.0.0.1:8888");
}
​
exports.start = start
    // module.exports = {
    //     start
    // }

        好了,我们的应用现在可以通过请求的URL路径来区别不同请求了—―这使我们得以使用路由(还未完成)来将请求以URL路径为基准映射到处理程序上。 ​ 现在我们可以来编写路由了,建立一个名为router.js 的文件,添加以下内容:

function router(pathname) {
    console.log(`即将路由请求${pathname}`);
}
exports.router = router
同时,我们会相应扩展index.js,使得路由函数可以被注入到服务器中:

var server = require('./server');
var router = require('./router');
​
server.start(router.router)

6.回调函数

Node.js 异步编程的直接体现就是回调。

        回调函数在完成任务后就会被调用,Node使用了大量的回调函数,Node所有API都支持回调函数。

        例如,我们可以一边读取文件,一边执行其他命令,在文件读取完成后,我们将文件内容作为回调函数的参数返回。这样在执行代码时就没有阻塞或等待文件IO操作。这就大大提高了Node.js 的性能,可以处理大量的并发请求。

回调函数一般作为函数的最后一个参数出现:

function foo1(name,age,callback){}
function foo2(value,callback,callback2){}

6.1阻塞代码实例

创建一个文件input.txt,内容如下:

天苍苍,野茫茫,风吹草低现牛羊

创建main.js文件,代码如下:

const fs = require("fs");
//同步(阻塞的)
let data = fs.readFileSync("./input.txt")
console.log(data.toString());
​
console.log("程序执行成功");

执行代码:

$ node main.js

6.2非阻塞代码实例

const fs = require("fs");
// 异步(非阻塞的)
fs.readFile('./input.txt', function(err, data) {
  if (err) {
     console.error(err.stack);
     return;
  }
  console.log(data.toString());
})
​
​
console.log("程序执行完毕");

7.事件循环

        Node.js是单进程单线程应用程序,但是通过事件和回调支持并发,所以性能非常高。

        Node.js的每一个API都是异步的,并作为一个独立线程运行,使用异步函数调用,并处理并发。

        Node.js基本上所有的事件机制都是用设计模式中观察者模式实现。 Nodejs单线程类似进入一个while(true)的事件循环,直到没有事件观察者退出,每个异步事件都生成一个事件观察者,如果有事件发生就调用该回调函数。

7.1事件驱动程序

        Node.js 使用事件驱动模型,当web server接收到请求,就把它关闭然后进行处理,然后去服务下一个web请求。

        当这个请求完成,它被放回处理队列,当到达队列开头,这个结果被返回给用户。 这个模型非常高效可扩展性非常强,因为webserver一直接受请求而不等待任何读写操作。(这也被称之为非阻塞式IO或者事件驱动IO) 在事件驱动模型中,会生成一个主循环来监听事件,当检测到事件时触发回调函数。

        整个事件驱动的流程就是这么实现的,非常简洁。有点类似于观察者模式,事件相当于一个主题(Subject),而所有注册到这个事件上的处理函数相当于观察者(Observer)。 Node.,js有多个内置的事件,我们可以通过引入events模块,并通过实例化EventEmitter类来绑定和监听事件,如下实例:

// 引入 events 模块
const events = require('events');
// 创建 eventEmitter 对象
const eventEmitter = new events.EventEmitter();

        以下程序绑定事件处理程序:

// 绑定 connection 事件处理程序
eventEmitter.on('connection', connectHandler);

        我们可以通过程序触发事件:

// 触发 connection 事件
eventEmitter.emit('connection');

7.2实例

// 引入 events 模块
const events = require('events');
// 创建 eventEmitter 对象
const eventEmitter = new events.EventEmitter();
​
// 创建事件处理程序
var connectHandler = function() {
    console.log('连接成功');
    // 触发 data_received 事件
    eventEmitter.emit('data_received');
}
​
// 绑定 connection 事件处理程序
eventEmitter.on('connection', connectHandler);
​
// 使用匿名函数绑定 data_receined 事件
eventEmitter.on('data_received', function() {
    console.log('数据接收成功');
})
​
// 触发 connection 事件
eventEmitter.emit('connection');
​
// 程序执行完毕
console.log("程序执行完毕");

结果: 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值