学习Node就绕不开异步IO, 异步IO又与事件循环息息相关, 而关于这一块一直没有仔细去了解整理过, 恰好最近在作项目的时候, 有了一些思考就记录了下来, 但愿能尽可能将这一块的知识整理清楚, 若有错误, 请指点轻喷~~前端
同步异步 & 阻塞非阻塞ajax
查阅资料的时候, 发现不少人都对异步和非阻塞的概念有点混淆, 其实二者是彻底不一样的, 同步异步指的是行为即二者之间的关系 , 而阻塞非阻塞指的是状态即某一方。浏览器
之前端请求为一个例子,下面的代码不少人都应该写过异步
$.ajax(url).succedd(() => { ...... // to do something })
同步异步
函数
若是是同步的话, 那么应该是客户端发起请求后, 一直等到serve处理请求完成后才返回继续执行后续的逻辑, 这样客户端和服务端之间就保持了同步的状态
。学习
若是是异步的话, 那么应该是客户端发起请求后, 当即返回, 而请求可能尚未到达服务端或者请求正在处理, 固然在异步状况下, 客户端一般会注册事件来处理请求完成后的状况, 如上面的succeed函数。ui
阻塞非阻塞
url
首先须要明白一个概念, Js是单线程, 可是浏览器并非, 事实上你的请求是浏览器的另外一个线程在跑。spa
若是是阻塞的话, 那么该线程就会一直等到这个请求完成以后才能被释放用于其余请求。线程
若是是非阻塞的话, 那么该线程就能够发起请求后而不用等请求完成继续作其余事情。
IO是什么?
I/O(英语:Input/Output),即输入/输出,一般指数据在内部存储器和外部存储器或其余周边设备之间的输入和输出。
异步IO操做
文件读取的方式是一次性所有读取,当文件过大的时候,一次性读取不只缓慢,并且影响用户体验,那么怎么实现分步读取呢,
这就得使用到异步IO的操做,像水流同样流出一段取得一段。
具体实现:
咱们建立一个文件读取流,先上代码
var fs = require("fs"); var data = ""; //声明一个空字符串来存读取的数据 var rs = fs.createReadStream("a.txt"); rs.setEncoding("utf-8"); //监听当有数据流入的时候 rs.on("data",function(chunc){ data += chunc; //将读取的数据拼接到data上。 console.log("..."); //读的过程当中,咱们打印三个点。 }); rs.on("end",function(){ console.log("没有数据了") });
咱们将 a.txt中的内容增长,以让读取时间变长,
代码中,建立main3.js写入上面的代码,使用 reateReadStream建立读取流对象,在对象上使用on监听“data”读取数据的事件,每读取一段数据,就会触发这个事件,当读取完毕, 就会触发“end”事件。
执行main3.js,咱们就能够看到下面打印的结果,从打印的多行"..."中,咱们就能够看出,读取了屡次才读完。
将读取到的数据,慢慢的写入 b.txt中
修改mai3.js中的代码为以下,增长了下面代码的 4/10/16行,4行表示创建一个写入流(若是写入的文件不存在,会自动建立一个文件),10行表示往文件写入东西,16行表示关闭写入流。
var fs = require("fs"); var rs = fs.createReadStream("a.txt"); var ws = fs.createWriteStream("b.txt"); //写入流 rs.setEncoding("utf-8"); //监听当有数据流入的时候 rs.on("data",function(chunc){ console.log("..."); //读的过程当中,咱们打印三个点。 ws.write(chunc,"utf-8"); //向文件写入东西 }); rs.on("end",function(){ console.log("没有数据了"); ws.end(); //关闭写入流 });
这样咱们异步的读取和写入文件就实现了
总结
之因此常常会混乱是由于没有说清楚讨论的是哪一部分, 因此同步异步讨论的对象时双方,而阻塞非阻塞讨论的市对象自身。