node.js哲学与核心原理
。提起node.js首先脑海中就会出现三个概念,单线程,非阻塞I/O,事件驱动
那么node.js的哲学是什么呢,简单说,用低性能的硬件解决web服务器高并发性能问题。
例在PHP中I/O是同步的阻塞的,也就是说cpu只有在磁盘驱动器读取完文件后才会执行后续操作
<?php $file_path = "test.txt"; $fp = fopen($file_path,"r"); $str = fread($fp,filesize($file_path));//这里是一个同步语句,CPU此时命令磁盘驱动器读取文件,此时CPU闲置了。 //而明明后面有一个计算任务,CPU如果能够在等待I/O结束的时候把它提前做掉多好! $sum = 0; for($i = 1; $i <= 100 ; $i++){ $sum += $i; } ?>
在node.js中因为事件环和非阻塞I/O的机制
const fs = require("fs"); fs.readFile('./2.txt', (err, data) => { if (err) { console.log(err); return; } console.log(data.toString()) }) //一些计算 var sum = 0; for (var i = 0; i <= 100; i++) { sum += i; } console.log(sum);
result:
5050
{"name":"XiuRr"}
用一张图可以清晰的表示两者的区别。
所以说node.js适合开发I/O多的业务,而不适合开发计算多的业务,因为其是单线程当计算业务繁重时就会被阻塞,其他用户将无法访问。
并且.node.js这种剑走偏锋的模式,也注定了其难以胜任安全性高,体量大的项目。
node.js应用非常广泛,并且其拥有世界上最大的开源库NPM,像python一样可以进行顶层路由设计等特点。
node.js本身是没有服务架构的,不同于php必须依赖于Apache、Tomcat、Nginx、IIS等HTTP服务器。
说白了node.js就是一个运行环境,可以在这个环境上跑JS,仅此而已,而python等语言即是语言又是平台,node.js使JS更加灵活不在局限与客户端。
node.js的事件环机制
node.js作为一个单独的JS运行环境,进行web开发时需要手动实现路由设计
比如简单实现一个静态路由设计
const fs = require("fs") const http = require("http") const url = require("url") const path = require("path") http.createServer((req, res) => { let pathname = url.parse(req.url, true).pathname; let extname = path.extname(pathname); // 如果没有扩展名表明是文件夹 if (!extname) { pathname = "/index.html" } //如果不是以/结尾,此时会造成浏览器识别图片路径层次有问题 if (pathname.substr(-1) !== "/") { res.writeHead(302, { "Location": pathname + "/" }) } fs.readFile("./public" + pathname, (err, data) => { res.end(data) }) }).listen(3000)
来一个最简单的动态路由设计
const fs = require("fs") const http = require("http") const url = require("url") const path = require("path") let data = { "100001": { "name": "小明", "yuwen": 69, "shuxue": 2 }, "100002": { "name": "小红", "yuwen": 29, "shuxue": 3 }, "100003": { "name": "小钢炮", "yuwen": 59, "shuxue": 100 } } http.createServer((req, res) => { // 获取查询字符串 res.setHeader("Content-Type", "text/html;charset=UTF-8"); // 编辑路由 let arr = req.url.match(/^\/student\/([\d]{6})$/); let studentNum = arr && arr[1] console.log(studentNum) if (req.url == "/") { res.end("首页"); } else if (req.url == "/music") { res.end("音乐频道"); } else if (req.url == "/news") { res.end("新闻频道"); } else if (data.hasOwnProperty(studentNum)) { res.end(data[studentNum].name + "语文" + data[studentNum].yuwen); } else { res.end("不存在"); } }).listen(3000)