NodeJS相关笔记(四)

1.io就是数据读写、数据流动
◆输入输出
◆文件操作的读写
◆网络操作中的请求与响应




2.事件驱动模型
◆主线程会去执行node的代码,把js代码放入队列,形成一个事件环
◆主线程会去把队列中的同步代码一个一个的取出来执行
◆在同步代码执行的时候会检查有没有异步代码
◆异步代码分为两种:1.异步非io,如setTimeOut()、setInterval()。2.异步io文件操作
◆如果是异步非io,那么就会在当前的同步代码执行完毕之后,再去执行异步非io的代码
◆如果是异步io,那么就会去线程池中取一条线程,用来帮助主线程执行异步io操作
◆主线程一直从队列中取代码来执行,当队列中没有代码了就会退出
◆线程池中的线程在没有异步io操作的时候就会休息
◆如果异步io操作有回调函数,那么子线程就会在执行异步io操作之后再把回调函数中的代码放回队列里,让主线程再去执行。
◆队列中每一项,都会有一个状态记录,主线程会轮询队列中的状态,异步io操作就靠这个状态来确定是否执行完毕。



3.项目迭代
◆加新功能
◆减旧功能
◆修改功能
◆用新技术重改一遍旧的项目
◆不停的更新版本:v(1),v(2),v(3),v(4)...


4.递归
◆自己调用自己
◆根据条件来停止自己调用自己
◆f(f()),f(f(f())),f(f(f(f()))),f(f(f(f(f()))))...


5.angularjs中的$http
◆then方法,里面包含两个函数,分别对应success和error:

$http({
method:'GET',
url:'xxx'
}).then(function(data){
//then的成功方法中返回的data是整个报文,如果要取里面的json数据,就使用data.data了,
这个和直接.suncess不一样的,.suncess返回的data就是then的成功方法里的data.data
},function(error){
//错误方法返回的error是一样的。
})



6.js调试
◆可以使用在js代码中加debuger,相当于在页面加断点,不过这是老的用法了。


7.nodejs调试
◆node内置调试器:命令调试法【
◇启动调试:node debug hello.js
◇常用命令:
△help:查看可用命令列表
△n(下一步):代码默认会从第一行开始调试,会跳出方法不去看方法里面的
△s(步入):进去方法里面,进去之后就n,如果再s可能就进去nodejs内部代码了。
△o(步出):进去方法里面后跳出方法

◆nodejs第三方工具调试:node-inspector【
◇一个第三方调试工具:node-inspector
◇https://github.com/node-inspector/node-inspector
◇安装:npm install -g node-inspector
◇启动调试器:node-inspector,保持挂起不要关闭
◇打开另一个命令台,以调试模式启动程序:node-debug foo.js
◇打开浏览器访问:http://localhost:8080/debug?port=5858
◇然后没报错的话,打开开发人员工具,你就可以像往常调试js代码一样,进行调试它,点击Sources。



◆Visual Studio Code调试:对node调试很亲和(推荐使用)【
◇打开新键窗口,打开文件夹
◇打开要调试的文件,按f5,选择nodejs环境,当然你如果只有nodejs环境那就不用选择,编辑器会生成一个launch.json
◇修改launch.json相关内容,主要是name和program字段,name是你起的调试名称,program是你选择的要调试的文件。
◇点击编辑器左侧长得像甲壳虫的那个按钮
◇点击左上角调试后面的按钮,启动调试
◇打上断点,开始调试(只要你会chrome调试,就很容易)
◇vscode它会根据的你的文件来判断你这需要什么,如js它就会去全局环境中去找nodejs,找不到那就是你没有配置好,如果你安装了nodejs,那么可能默认就是nodejs了
◇vscode调试资料的网站:http://i5ting.github.io/vsc/(vsc教程)

◆WebStorm调试:【
◇在要调试的脚本中打好断点之后右键选择Debug(调试运行)即可开启调试,只要你会chrome调试,点击下一步、步入、强制步入、步出,也可以通过命令
△F8  Step over
△F7  Step into
△Shift + F7 Smart step into
△Shift + F8  Step out
△Alt + F9  Run to cursor
△Alt + F8  Evaluate expression
△F9  Resume
△Ctrl + F8  Toggle breakpoint
△Ctrl+Shift+F8  View breakpoints

◆重型的开发工具叫IDE(集成开发环境),IDE中一般都有调试工具


8.ECMAScript6
◆因为标准所以需要兼容再兼容
◆http://www.ecma-international.org/ecma-262/6.0
◆不同版本浏览器对ES6的支持情况:kangax.github.io/es5-compat-table/es6/
◆Node.js因为采用了Chrome V8引擎,所以对于ES6的支持非常好,运行在服务器端,Node开发不用考虑兼容性问题
◆http://es6.ruanyifeng.com/这个是阮一峰写的ECMAScript6


8.ECMAScript6新语法
◆ECMAScript5中的use strict是一个很重要的东西,表示让语法更加严格,这样你就不会因为写了保留字而导致在未来出现兼容性的问题了。
◆'use strict':
◇消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为,如你直接写a=0;,鬼知道这是个什么鬼
◇消除代码运行的一些不安全之处,保证代码运行的安全,如果你使用了保留字(未来的关键字),直接给你报错,如Unexpected strict mode reserved word,这样的错误说明你用了保留字做为参数名,它的保留字啊,其实都是其它语言里出现过的关键字。
◇为未来新版本的Javascript做好铺垫,因为只有这样才能让低版本的js文件里的代码兼容性更好

◆let:定义变量,使用let后,一个作用于下,同一变量名只能够定义一次,这和var里的变量提升的机制不一样,并且作用域更加严格了,不再是只能使用function来定义作用域了,使用let后,let定义的变量的作用域就是一个花括号内了。
◆块儿级作用域:凡是被{}包裹的代码就属于一个代码块儿,其作用类似于(function(){})()在这里面的{}。
◆const:定义常量,原来是通过变量名全部大写来约定为常量,现在可以使用const直接定义常量,并且你改常量就会报错,如PI或者你nodejs引入一个包返回的对象赋值给一个常量名。
◆nodejs里面你完全可以使用let和const来代替var。
◆箭头函数:()=>{}相当于function(){}



9.字符串扩展
◆includes(s):表示是否找到了指定s参数字符串
◆startsWith(s) :表示参数字符串是否在源字符串的头部
◆endsWith(s):表示参数字符串是否在源字符串的尾部
◆s.repeat(n):将原字符串s重复n次并返回,这个很不错。
◆模板字符串``,是用``和${}来代替字符串拼接
◇增强版的字符串:用反引号`作为标识,以前是用"或者'
◇模板字符串中所有的空格和缩进都会被保留
◇在模板字符串中嵌入变量:${变量名},可以有多个,就是原来使用"hilo"+name+"....";,现在可以这样`hilo${name}....`;,效果一样了,非常方便
◇模板字符串可以是原始的:String.raw`hello world\n`,通过String.raw`hello world\n`可以返回字符串"hello world\n",也就是说可以转换的。



10.异步流程控制的解决方案 
◆超过四个异步嵌套就成了回调地狱火焰山
◆相应的文章:https://cnodejs.org/topic/560dbc826a1ed28204a1e7de
◆promise(一种规范产生的一个对象),其实类似于.then之间传递的一个对象,有成功有失败。
◆代码原理,将定义一个方法,内部返回一个Promise对象,你将成功要执行的方法和失败要执行的方法作为参数传递进去,然后Promise对象中定义了一个then方法,这个方法会接受你传递进去的两个参数,并且会根据你这个两个参数调用之后返回的值来决定是否继续返回新的Promise对象,就这样Promise对象就可以在then中流动了,这样就使用了同步的方式去写异步的代码了,很好的控制了异步嵌套的问题,return 表示同步,callback表示异步【
'use strict'
const fs=rquire('fs');
var rf=function(){
//resolve表示成功、reject表示失败
return new Promise(function(resolve,reject){
fs.readFile('./a.js','utf8',(err,data)=>{
if(err){
//失败
return reject(err);
}else {
//成功
return resolve(data);
}
})
})
}
rf().then(function(data){
如果你还想继续往下执行,可以再renturn一个Promise对象回去
console.log(data);
},function(err){})

◆其实真正then方法不需要判断你的返回值,而是作为一个代理方法,无论成功失败是否返回值,then都会自己返回一个Promise对象给你,链式变成return this。





11.Buffer
◆十六进制
◆字节的转化

1汉字=2字节  00100010 00000000
1字节(Byte)=8字位=8个二进制数 
1字位(bit)=1个二进制数 
1B=8b 
1KB=1024B 
1MB=1024KB 
1GB=1024MB 

◆fs.readFile('./1.js',(err,data){
//返回的是一个Buffer,是 十六进制的机器码转化后的字节,因为第二个参数应该传递'utf8'
console.log(data);
})
◆创建Buffer
◇Buffer 是一个像 Array 的对象,它的元素为16进制的两位数(0-255的值),主要用于操作字节
◇Buffer 是一个全局对象,使用的时候不需要 require了
◇new Buffer(size),创建一个Buffer并设置大小,返回的对象你像操作数组对象一样就可以了,如buf[0]=254;,输出的时候显示这个地方为FE
◇new Buffer(str,[encoding]),创建一个Buffer并传递参数字符串,然后按照指定的编码进行解析成二进制码。
◆Buffer的一些属性和方法
◇buf[index] 通过下标访问 buffer 的某个字节的数据
◇buf.indexOf(value,[byteOffset],[encoding]) 查找某个字符在 buffer 内存中的字节下标
◇ buf.includes(value,[byteOffset],[encoding])
◇ buf.length
◇ buf.slice([start,[end]])
◇ buf.toString([encoding],[start], [end])
◇ buf.write(string,[offset],[length],[encoding])

◆开源中国 官网网站提供的一个工具页面:http://tool.oschina.net/
◆解决 Node 原生不支持的一些编码 通过 第三方包:iconv-lite(https://www.npmjs.com/package/iconv-lite),第三方包可以解决 gbk 等编码不支持的问题




12.文件流:用来读大文件
◆fs.readFile()和fs.writeFile()只能够读读小文件,读大文件,内存就爆炸了。
◆对大文件的处理,例如下载之类的,可以通过文件流的形式传输大文件【
'use strict'
const fs=require('fs');
//将要读文件变成一缸水
    const rs = fs.createReadStream(p1);
//将要写的文件变成一个缸
    const ws = fs.createWriteStream(p2);
//使用管道通一通 ok
    rs.pipe(ws);

◆控制文件流:监听stream对象里面的事件来控制读写流【
'use strict'
const fs=require('fs');
//将要读文件变成一缸水
    const rs = fs.createReadStream(p1);
//将要写的文件变成一个缸
    const ws = fs.createWriteStream(p2);
//没读到一下块儿就触发一次事件,chunk就这一下块儿的buffer
//读数据的事件
rs.on('data',function(chunk){
console.log('读了一下',chunk.length);
ws.write(chunk);
});
//写数据结束的事件
rs.on('end',function(){
console.log('读完了');
ws.end();
})

◆读取流的时候或者进度:【
'use strict'
const fs=require('fs');
//将要读文件变成一缸水
    const rs = fs.createReadStream(p1);
//将要写的文件变成一个缸
    const ws = fs.createWriteStream(p2);
//取文件相对应的stats对象
    var stats=fs.statSync('p1');
//文件大小
    var count=stats.size;
//传输的文件默认传了0
    var data=0;


//没读到一下块儿就触发一次事件,chunk就这一下块儿的buffer
//读数据的事件
rs.on('data',function(chunk){
//已经读了多少
data+=chunk.length;
console.log(parseFloat(data/count*100)+'%');
ws.write(chunk);
});
//写数据结束的事件
rs.on('end',function(){
console.log('结束');
ws.end();
})


















猜你喜欢

转载自blog.csdn.net/jwlLWJ_2018/article/details/80748301