[Node入门] => 读书笔记(一)
来源:互联网 发布:淘宝出售假冒商品投诉 编辑:程序博客网 时间:2024/06/04 18:37
学习内容
- Node入门
学习笔记
1. 一个基础的HTTP服务器
[Node入门] 主文件叫做index.js或多或少是个标准格式,把服务器模块放进叫server.js的文件
// 使用require指令载入http模块const http = require('http');// 创建主机名和端口const hostname = '127.0.0.1';const port = 1337;// 创建服务器方法http.createServer()http.createServer((req, res) => { // 发送http请求头,http状态码200,内容类型 res.writeHead(200, { 'Content-Type': 'text/plain' }); // 发送相应数据'Hello World' res.end('Hello World\n');}).listen(port, hostname, () => { // 终端listen端口,主机 console.log(`Server running at http://${hostname}:${port}/`);});
方法:http.createServer([requestListener])
说明:返回一个http.Server的新实例
来源:https://nodejs.org/dist/latest-v5.x/docs/api/http.html
注:’Hello World’ 样例来自NodeJs官网(https://nodejs.org/en/about/),使用了ES6语法。
2. 基于事件驱动的回调
2.1 阻塞、非阻塞、同步、异步
说明阻塞,非阻塞,异步,同步的一个来自网络的例子,作者不明:
老张爱喝茶,废话不说,煮开水。
出场人物:老张,水壶两把(普通水壶,简称水壶;会响的水壶,简称响水壶)。
1 老张把水壶放到火上,立等水开。(同步阻塞)
老张觉得自己有点傻
2 老张把水壶放到火上,去客厅看电视,时不时去厨房看看水开没有。(同步非阻塞)
老张还是觉得自己有点傻,于是变高端了,买了把会响笛的那种水壶。水开之后,能大声发出嘀~~~~的噪音。
3 老张把响水壶放到火上,立等水开。(异步阻塞)
老张觉得这样傻等意义不大
4 老张把响水壶放到火上,去客厅看电视,水壶响之前不再去看它了,响了再去拿壶。(异步非阻塞)
老张觉得自己聪明了。
所谓同步异步,只是对于水壶而言。普通水壶,同步;响水壶,异步。虽然都能干活,但响水壶可以在自己完工之后,提示老张水开了。这是普通水壶所不能及的。同步只能让调用者去轮询自己(情况2中),造成老张效率的低下。
所谓阻塞非阻塞,仅仅对于老张而言。立等的老张,阻塞;看电视的老张,非阻塞。情况1和情况3中老张就是阻塞的,媳妇喊他都不知道。虽然3中响水壶是异步的,可对于立等的老张没有太大的意义。所以一般异步是配合非阻塞使用的,这样才能发挥异步的效用。
2.2 回调
[Node入门] 我们给某个方法传递了一个函数,这个方法在有相应事件发生时调用这个函数来进行回调 。
个人理解:
1. 老张 => 服务器, 水壶 => 用户请求。我们不知道水壶什么时候烧开水,亦即服务器不知道用户请求什么时候到来。
2. 假如使用响水壶,响水壶响了,亦即所谓“有相应事件发生时”。
3. Node不像PHP,每多一个水壶就需要多一个老张来照看,100个请求需要100个进程;对于Node,一个老张照顾所有的响水壶,100个请求一个进程管理,因为这个过程是异步的,非阻塞的。
2.3 实例
书中,用这样一个类似例子,来解释了基于事件驱动的回调
const http = require('http');const hostname = '127.0.0.1';const port = 1337;http.createServer((req, res) => { // 每一次请求,服务器刷新一段文本 console.log('Request received.'); res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Hello World\n');}).listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`);});
3. 封装服务器模块
创建一个server.js如下:
const http = require('http');const hostname = '127.0.0.1';const port = 1337;function start() { http.createServer((req, res) => { console.log('Request received.'); res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Hello World\n'); }).listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`); });}// 导出函数exports.start = start;
通过创建index.js调用上述封装好的服务器模块,如下
// 读取服务器模块var server = require('./server.js');// 启动服务器server.start();
4. 路由
4.1 准备工作:获取请求的URL路径
例如:一个URL 对象'http://user:pass@host.com:8080/p/a/t/h?query=string#hash'
其中:pathname是'/p/a/t/h'
,search是'?query=string'
,path则是'/p/a/t/h?query=string'
等等,具体可从官方API中查询。
来源:https://nodejs.org/dist/latest-v5.x/docs/api/url.html
4.2 使用依赖注入,添加路由模块
创建一个router.js路由模块
// 简单的输出下请求路径信息function route (pathname) { console.log(`About to route a request for ${pathname}`);}exports.route = route;
更改server.js实现:
const http = require('http');// 载入url模块const url = require('url');const hostname = '127.0.0.1';const port = 1337;function start(route) { http.createServer((req, res) => { // 获取请求中的url路径 var pathname = url.parse(req.url).pathname; console.log(`Request for ${pathname} received.`); // 添加路由功能 route(pathname); res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Hello World\n'); }).listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`); });}exports.start = start;
扩展index.js
var server = require('./server.js');var router = require('./router.js');server.start(router.route);
至此,一个简单的包含路由模块,路由模块的hello world级别的应用构建完毕。
- [Node入门] => 读书笔记(一)
- [Node入门] => 读书笔记(二)
- [Node入门] => 读书笔记(三)
- Node入门(一)
- 读书笔记之-node入门
- 《Node入门》读书笔记
- node.js学习一(node入门)
- 从零开始node.js入门项目(一)
- node.js笔记(一)入门
- node入门(一)--内置模块
- 《深入浅出Node.js》读书笔记+个人思考(一):模块机制
- 机器学习入门读书笔记一(概述)
- MySQL数据库入门--读书笔记(一)
- Node.js-入门一--快速入门
- node.js入门(一)安装和第一个页面
- Node.js初体验之入门(一)
- Node.js教程(一)入门和学习资源
- 入门到放弃node系列之网络模块(一)
- 使用注解springmvc配合jsp/ajax/json,实现简单的jsp遍历后台数据
- Java compiler level does not match the version of the installed Java project facet
- JNI介绍
- 线程锁错误案例
- linux原始套接字(1)-arp请求与接收
- [Node入门] => 读书笔记(一)
- Spring中bean的作用域
- 减少C++代码编译时间的方法
- QT发展简史
- 统一配置中心
- LeetCode Same Tree
- 2016年1月28日学习进度
- 设置约束的masonry的使用
- 让你的C程序更有效率的 10 种方法