nodejs学习笔记(一)


  • 参考资料
    https://blog.csdn.net/u011483658/article/details/115855805

  • 目标文件位置(mac): documents/projects/nodejs

  • 初始化
    在目标*文件夹下 npm init -y

原生nodejs

NODEJS与其他后台语言有何不同

优点:
  1. nodejs与前端开发语言js的对象、语法等等是一模一样的,她们来自同一个系统。前端学习成本低。
  2. 性能还可以。比不了c、c++,但是比python快80+倍。(运行环境chrome v8 引擎)。nodejs与前端是同一套体系,可以做到“无缝链接”,因此效率高。尤其是适合开发并发数高、但是单个线程计算量小的系统(与java相反)。
  3. 前后台配合方便。

缺点
java有丰富的库的支持。nodejs还是太年轻。

用处

1.服务器: 小型服务器(某个频道、某个小的应用)、中间层。 中间层图示:
2.工具: 测试类工具、构建类工具(grunt、gulp、webpack)、爬虫抓取类

nodejs搭建服务器

服务器种类繁多(apche、nginx、nodejs、iis写的服务器........)、浏览器种类也很繁多(firefox、chrome、IE......),她们彼此建立联系需要一个规范,这个规范就是“http协议”。 “http协议”是个很繁杂的东西,故而需要将它“包装起来”,便于使用。因此,问题,转化为如何使用包装起来的“http”模块。 代码写好了之后如何运行: 命令行cd进入到代码所在的目录:node filename.js 代码的书写与前端代码的书写并没有两样:

			let a=12; 
			let b=20; 
			console.log(a+b) ;
			let c=new Date(); 
			console.log(c);
			console.log(c.getFullYear()); 
			console.log(c.getDay()) 
			console.log(c.getHours()) 
			console.log(c.getMinutes()) 

结果不是在浏览器上显示的,而是在命令行中显示的: >

http模块

http模块是众多的模块中的一个,可以在api中查找: http://nodejs.cn/api/

任何服务器程序都必须要带有监听 listen():

const http = require("http");
let server = http.createServer((req, res) => { 
    console.log("我开始执行了")
})
server.listen(9600);
“9600”是监听的端口。端口的存在主要是出于同一台电脑可以有多个后台程序运行的情况,来进行考虑的。同一台服务器(电脑)上可以同时运行好几个服务(后台程序),当客户端的请求过来了的时候,找到服务器,会出现无法跟好几个服务中某一个具体的服务无法实际对应的问题,因此,在确定了某一台服务器(电脑)之后,还需要将服务器(电脑)上的每一个具体的服务(后台程序)进行标注,以便区分------**端口就这么产生了**。

要注意的是,上文的代码没有传递过来具体的数据,因此,在浏览器中打开的时候,会出现“空等”的现象(不停的转圈,正时针表示正在加载数据,反时针方向表示等待服务器传送过来的数据。本次的空等现象是由于没有res.end(),浏览器不知道是否已经全部加载完数据,只能等待的过程):

浏览器刷新几次,即向服务器请求几次,这在后台中也能显示出来:

http.createServer((req,res)=>{})

更完备的代码如下:

		const http = require("http");
		let server = http.createServer((request, response) => { 
			response.write("abc")
			// response.write(abcd)  //错误写法
			console.log("我开始执行了")
			response.end()
		})
		server.listen(9600);

注意:

  1. http.createServer(()=>{})有2个参数,request和response:
    request(请求、接受数据、输入)<-----------> response (响应、输出到浏览器)
  2. response又有两个参数:response.write()和response.end()。response.write()表示向浏览器窗口中写入数据,response.end()表示写入数据结束了,浏览器不用再“空转等待”了。
    3.console.log()会执行2次(高级浏览器)。ie7等低版本可能执行1次。

console.log()执行2次的原由

	 console.log(request.url)
	console.log("我开始执行了")


先执行一次 console.log(request.url),输出“/”,再执行1次console.log(request.url),输出“/favicon.ico”(favicon是网站图标)

总结

1.nodejs是一门还不错的语言,跟javascript有很多的类似处。
2.模块。强烈依赖于模块。http模块只是其中的一个比较重要的模块。
3.nodejs的特色是足够的简单。为了保持这个优点,nodejs采用的是单线程而放弃了复杂多变的多线程。同时,nodejs也兼顾到了性能的考虑,引进了异步、非阻塞的技术。即:nodejs是一个异步非阻塞的单线程技术。
4.nodejs作为中间层如下的好处:1.安全性提高,懂java的太多了,欺负暂时还不了解nodejs的小白,攻破java三大框架的漏洞后,还有nodejs等着你攻破2.性能,比php强80倍3.前后台方便交互。


题外话:深克隆浅克隆

	<script>
		let a=[{a:15,b:16},2,3,4,5,6]


		// 改变了b的同时,改变了a,a和b是同一个个体。非浅克隆非深克隆
		// let b=a;
		// b.push(99) //数组a也push了一个99

		// a、b不再是同体。
		//浅克隆(关于克隆的理解:一旦克
		//隆出来,即是两个不同的个体,a的
		//变化不会导致b的变化,b的变化也
		//不会导致a的变化。区别于a=b),
		//只能克隆一层[],[]里面的json无法
		//克隆,两者在数组中的json依旧关联
		// let b=a.concat()
		// b.push(100) //数组a中没有push进100,两者不关联。
		// b[0].a=19 //数组a中的json也发生
		//了变化:a[0].a=19,两者在数组内
		//的json这个层面依旧产生了关联

		// 深克隆(虽然是从你那儿复制过来的,但是两者已经是独立的两个个体,即使是数组中包含的json也不会彼此之间产生关联了!)
		let b=JSON.parse(JSON.stringify(a));
		b[0].a=19
		b[0].b=101

		console.log(a)
		console.log(b)
	</script>

其他模块

此部分内容,再gitee中位于other_moudules文件夹中。各个模块位于该文件夹下的子文件夹。

两个可供参考的网址:
http://api.nodejs.cn/
http://nodejs.cn/api/

assert模块

代码块:

			const assert =require('assert');
			function sum(a,b) {
			   // assert(条件,“一段话”)
				assert(arguments.length==2,"必须传递2个参数")
				assert(typeof a =="number","第一个参数必须是数字")
				assert(typeof b =="number","第2个参数必须是数字")
				return a+b;
			}
			console.log(sum(5,"abc")) 

报错:

Buffer fs

fs模块

服务器几乎全部是异步模式的,而fs模块(文件的读写)的操作,对于异步的要求明显要更高,注定是异步的。
代码:

			const fs = require("fs");
			 fs.readFile("../fileSystem.txt", (err, data) => {
			 
			// console.log(data);
			// console.log(err);

			// 建议采用if-else,将格式固定下来:
			if (err) {
				console.log("有错误")
			}
			else {
				console.log(data);
				console.log(data.toString())
			}
		})
		// ! 运行几次,会产生几次的fileSystem.txt!???
		fs.writeFile("../fileSystem_1.txt", "覆盖readfile_1", err => {
			if (err) {
				console.log("写入失败")
			} else {
				console.log("写入成功")
			}
		})
			//追加的时候使用appendFile
			fs.appendFile("../fileSystem_1.txt","追加++",err=>{})
		// ! readFile、writeFile的联合使用以及将buffer中的
		// ! 16进制文件转化为字符串之后,破坏了图像文件
		fs.readFile("../pic.png", (err, data) => {
			if (err) {
				console.log("有错误")
			}
			else {
			//破坏图像文件
				fs.writeFile("../pic2.png", data.toString(), (err) => {})
			}
		})

错误和正确的时候,会出现的提示(正确的时候显示的是16进制的iscode):

并不是所有的文件都需要.toString(),在你确定需要.toString()的时候,你必须确保是字符串文件,如果不是比如说是图像文件,则会将原来的二进制图像文件破坏掉,出现下列的错误:

c++ addons (c++插件模块)

所有的语言在性能上,跟c/c++比,无可比性。

多进程:process 、child_process、cluster

nodejs设计的时候,为了足够的简单,本身是单进程、单线程的模式。而将多进程(非多线程,不支持多线程)放在:process 、child_process、cluster中。
提供了一种选择,但是没有改变其设计初衷。

crypto(加密)模块

本质还达不到“加密”程度,可以称之为“签名”,包括了md5、sha-256系列
http://nodejs.cn/api/crypto.html

			const crypto = require('crypto');
			const secret = 'abcdefg';
			const hash = crypto.createHmac('md5', secret)
							   .update('uck jdd')
							   .digest('hex');
			console.log(hash);

os模块

http://nodejs.cn/api/os.html#os_os

		const os = require('os');
		console.log(os.EOL);
		console.log(os.arch());
		console.log(os.cpus());
		console.log(os.hostname());
		console.log(os.loadavg());

path 模块

http://nodejs.cn/api/path.html#path_path

		const path=require("path")
		console.log(path.parse('/目录1/目录2/文件.txt'))

相关