node.js零基础详细教程(4):node.js事件机制、node异步IO操作
第四章 建议学习时间2小时 课程共10章
学习方式:详细阅读,并手动实现相关代码
学习目标:此教程将教会大家 安装Node、搭建服务器、express、mysql、mongodb、编写后台业务逻辑、编写接口,最后完成一个完整的项目后台,预计共10天课程。
node.js事件机制
node.js是单线程,但是通过事件和回调支持并发,可以实现非常高的性能。
node.js所有的API都是通过异步调用。第一堂课的时候,我们写过一个同步和异步的示例(如下),当初说到:同步代码先执行完成,然后才执行异步代码。
setTimeout(function(){
console.log(1000000000);
},0); for(var i=0; i<1000; i++){
console.log(i);
}
而对于异步的多个代码,它们的执行顺序是怎样的呢?试试下面的代码:
今天的代码我们放到一个新的文件夹 中,为了完成下面的文件读取,我们需要提前准备一个a.txt的文件(注意:文件格式最好是uft-8)
main.js中写入如下代码:
var fs = require("fs"); //node 内置模块可直接引入 fs:文件系统操作模块
fs.readFile("./a.txt","utf-8",function(err,data){ //读取文件
if(err) throw err;
console.log(data);
});
setTimeout(function(){
console.log("定时器打印!");
},0);
使用 node 运行 main.js后,你会发现定时器的先打印,(增加定时器的触发时间,你会发现,打印的顺序会改变。)
具体的异步代码执行顺序,是由node.js内部机制控制的,我们很难准确预知。这里给大家介绍一下node.js的事件模型:
Node.js 使用事件驱动模型,当web server接收到请求,就把它关闭然后进行处理,然后去服务下一个web请求。
当这个请求完成,它被放回处理队列,当到达队列开头,这个结果被返回给用户。
这个模型非常高效可扩展性非常强,因为webserver一直接受请求而不等待任何读写操作。(这也被称之为非阻塞式IO或者事件驱动IO)
在事件驱动模型中,会生成一个主循环来监听事件,当检测到事件时触发回调函数。
回调函数
回调函数就是将一个函数作为另一个函数的参数传入,作为另一个函数内部执行的函数。
我们上面示例中的文件读取方法中,第三个参数是一个回调函数,当文件读取完成,就会自动调用这个函数。
fs.readFile("./a.txt","utf-8",function(err,data){ //读取文件
if(err) throw err;
console.log(data);
});
上面的回调是封装好的,那么我们自己来写一个回调函数的实现样子:
创建 一个js文件,写入如下代码:
function fn01(data,callback){
if(data){
callback("",data);
}else{
var err = new Error("错误了");
callback(err)
}
} fn01("aa",function(err,data){
if(err){
console.log("错误"+err);
}else{
console.log(data);
}
})
上面代码是回调函数的标准模型,我们在调用 fn01的时候,传入了两个参数,第一个是字符串,第二个是一个回调函数,当参数传入以后。我们来看fn01的主方法,方法中检测第一个参数的存在情况来,然后执行callback方法,也就是执行了当参数传入的那个方法。
异步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(); //关闭写入流
});
这样我们异步的读取和写入文件就实现了
好,今天就讲这么多,明天将讲解:express 路由。
node.js零基础详细教程(4):node.js事件机制、node异步IO操作的更多相关文章
- node.js零基础详细教程(3):npm包管理、git github的使用
第三章 建议学习时间4小时 课程共10章 学习方式:详细阅读,并手动实现相关代码 学习目标:此教程将教会大家 安装Node.搭建服务器.express.mysql.mongodb.编写后台业务逻辑 ...
- node.js零基础详细教程(5):express 、 路由
第五章 建议学习时间4小时 课程共10章 学习方式:详细阅读,并手动实现相关代码 学习目标:此教程将教会大家 安装Node.搭建服务器.express.mysql.mongodb.编写后台业务逻辑. ...
- node.js零基础详细教程(2):模块化、fs文件操作模块、http创建服务模块
第二章 建议学习时间4小时 课程共10章 学习方式:详细阅读,并手动实现相关代码 学习目标:此教程将教会大家 安装Node.搭建服务器.express.mysql.mongodb.编写后台业务逻辑 ...
- node.js零基础详细教程(7.5):mongo可视化工具webstorm插件、nodejs自动重启模块Node Supervisor(修改nodejs后不用再手动命令行启动服务了)
第七章 建议学习时间4小时 课程共10章 学习方式:详细阅读,并手动实现相关代码 学习目标:此教程将教会大家 安装Node.搭建服务器.express.mysql.mongodb.编写后台业务逻辑. ...
- node.js零基础详细教程(6):mongodb数据库操作
第六章 建议学习时间4小时 课程共10章 学习方式:详细阅读,并手动实现相关代码 学习目标:此教程将教会大家 安装Node.搭建服务器.express.mysql.mongodb.编写后台业务逻辑. ...
- node.js零基础详细教程(7):node.js操作mongodb,及操作方法的封装
第七章 建议学习时间4小时 课程共10章 学习方式:详细阅读,并手动实现相关代码 学习目标:此教程将教会大家 安装Node.搭建服务器.express.mysql.mongodb.编写后台业务逻辑. ...
- node.js零基础详细教程(6):mongodb数据库操作 以及导入导出
第六章 建议学习时间4小时 课程共10章 学习方式:详细阅读,并手动实现相关代码 学习目标:此教程将教会大家 安装Node.搭建服务器.express.mysql.mongodb.编写后台业务逻辑. ...
- node.js零基础详细教程(1):安装+基础概念
第一章 建议学习时间2小时 课程共10章 学习方式:详细阅读,并手动实现相关代码 学习目标:此教程将教会大家 安装Node.搭建服务器.express.mysql.mongodb.编写后台业务逻辑. ...
- nodejs零基础详细教程2:模块化、fs文件操作模块、http创建服务模块
第二章 建议学习时间4小时 课程共10章 学习方式:详细阅读,并手动实现相关代码 学习目标:此教程将教会大家 安装Node.搭建服务器.express.mysql.mongodb.编写后台业务逻辑 ...
随机推荐
- git远程库代码版本回滚方法
最近使用git时, 造成了远程库代码需要回滚到之前版本的情况,为了解决这个问题查看了很多资料. 问题产生原因: 提交了错误的版本到远程库. 以下是解决的方法, 供大家参考: 1.对本地代码库进行回滚 ...
- Redisson入门
Redisson入门 Author:Ricky Date:2017-04-24 Redisson概述 Redisson是架设在Redis基础上的一个Java驻内存数据网格(In-Memory Dat ...
- JTextArea自动换行以及设置滚动条
应将JTextArea置于JScrollPanel中若要使只有垂直滚动条而没有水平滚动条,使用JTextArea.setLineWrap(true),自动换行. 文本换行代码片段如下: JTextAr ...
- 关于System.Windows.Forms.DateTimePicker的一个Bug
几天接到客户的反馈,说系统无法查询2017年2月份的账单,原因是没办法选择2017年2月份,没办法选择2月份???,马上开启vs,运行系统,应为市去年的系统,测试数据也是去年的,就查询了2016年2月 ...
- 在android中,如何去掉webview读取网页后点击网页上的按钮出现的方框
参考:http://blog.sina.com.cn/s/blog_64056edc0100xt3l.html <style type="text/css"> .bor ...
- MySQL对innodb某一个表进行移动
(步骤:建表, 禁用表空间,复制表空间,重用表空间) mysql> desc test; +-------+-------------+------+-----+---------+---- ...
- Asp.net mvc 小试牛刀一:多语言支持
最近因为项目需要又从UWP开发转到了Asp.net mvc 开发,由于也不是什么老手,所以就将项目常见的一些技术问题记录一下自己的解决方案. 第一个需求:用户可以自由切换界面显示语言. 解决方案一:界 ...
- web乱码解决了
web容易乱码,最近有乱码了,透死了! 搞了半天,终于好了: String comment = new String(request.getParameter("comment") ...
- Centos5搭建vsftpd服务
更换镜像源 由于centos5已经历史久远,内置的镜像源已经不能用.看: 因此,我手工更换了阿里云的源.(ps:我本来是想用网易的源,但不知为什么,这个源在安装vsftpd时提示http 404错误) ...
- Android相机是如何获取到图像的
在研究zxing的过程中,脑袋中一直有个疑惑,那个相机并没有拍照,它是怎么获取图像的 带着这个疑惑查看Camera源码 Camera源码中有这样一个接口: public interface Previ ...