Node.js之路【第三篇】NodeJS异步实现
NodeJS异步实现
Node.js异步编程的直接体现就是回调,它依托于回调来实现,但不能说使用了回调他就是异步了
回调函数在完成任务后就会被调用,Node使用了大量的回调函数,Node所有的API都支持回调函数
例如:我们可以一边读取文件一边执行其他命令,在文件读取完成后,我们将文件内容作为回调的参数返回,这样执行代码的时候就不会有阻塞或等待I/O操作
这样就打打提高了Node.js性能,可以处理大量的并发请求。
一、阻塞代码示例
1、创建一个测试文件text.txt文件内容如下:
文件I/O操作:open the file ==>帅哥很帅
创建index.js文件
#!/usr/bin/env node
var fs = require("fs");
var data = fs.readFileSync('test.txt');
console.log(data.toString());
console.log('帅哥执行命令测试~~~');
2、执行结果
LuoTimdeMacBook-Pro-2:bin luotim$ node index.js 文件I/O操作:open the file ==>帅哥很帅 帅哥执行命令测试~~~
从结果上可以看出来先进行了I/O操作才执行的输出命令
二、非阻塞代码的实现
修改代码
#!/usr/bin/env node
var fs = require("fs");
fs.readFile('test.txt',function (error,data) {
if (error) return console.error(error);
console.log(data.toString());
});
console.log("异步程序测试~~");
2、执行结果
LuoTimdeMacBook-Pro-2:bin luotim$ node index.js 异步程序测试~~ 文件I/O操作:open the file ==>帅哥很帅
从结果上就可以看出第一个程序在文件读取完后才执行完程序,第二个实例我们不需要等待文件读取完这样就可以在读取文件的同时执行后续的代码,大大提高了程序性能。
对于Nodejs来说阻塞是按顺序执行的,而非阻塞不需要按照顺序执行直接把相关的I/O操作交给回调函数执行。
Node.js事件循环
Nodejs是单进程和单线程应用程序,但是通过事件和回调支持并发(看上面异步实现),所以性能非常高。
并且Nodejs的每一个API都是异步的,并作为独立的一个线程运行,使用异步函数调用,并处理并发!
Nodejs基本上所有的事件机制都是使用设计模式中“观察者模式”实现
#观察者模式 观察者模式(有时又被称为发布(publish )-订阅(Subscribe)模式、模型-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。 在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。 这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。
Node.js单线程类似进入一个while(true)的事件循环,知道没有事件观察者退出,每个异步事件都生成一个事件观察者,如果没有事件发生就调用该回调函数。
事件驱动程序
Node.js使用事件驱动模型,当web server接收到请求,就把他关闭然后进行处理,然后去服务下一个web请求。
当这个请求完成,它被放回处理队列中,当到达队列开头,这个结构就返回给用户。
因为webserver一直接受请求不等待任何的I/O读写操作(非阻塞I/O或者事件驱动I/O)
整个的驱动流程就是如上图这样实现的,非常简洁.
二、通过events模块来绑定和触发事件
1、导入模块并实例化对象
//引入events模块
var events = require("events");
//创建evenEmitter对象
var evenEmitter = new events.EventEmitter();
2、绑定定事件处理程序,当事件触发后执行的程序
//绑定事件及事件的处理程序
evenEmitter.on('evenName',eventHandler);
3、可以通过程序来触发
//我们可以通过程序触发事件
evenEmitter.emit('evenName');
实例:
#!/usr/bin/env node
//引入events模块
var events = require("events");
//创建evenEmitter对象
var eventEmitter = new events.EventEmitter();
// 创建事件处理程序
var connectHandler = function connected() {
console.log('连接成功。');
// 触发 data_received 事件
eventEmitter.emit('data_received');
};
// 绑定 connection 事件处理程序
eventEmitter.on('connection', connectHandler);
// 使用匿名函数绑定 data_received 事件
eventEmitter.on('data_received', function(){
console.log('数据接收成功。');
});
// 触发 connection 事件
eventEmitter.emit('connection');
console.log("程序执行完毕。");
梳理流程图:(用于梳理)事件的绑定执行
Node.js之路【第三篇】NodeJS异步实现的更多相关文章
- Node.js之路【第一篇】初识Node.js
什么是Node.js 1.Node.js就是运行在服务端的JavaScrip. 2.Node.js是一个基于Chrome JavaScrip运行时简历的一个平台. 3.Node.js是一个非阻塞I/O ...
- Node.js入门教程 第三篇 (模块及路由)
Node.js的模块 Node.js的模块与传统面向对象的类(class)不完全相同.Node.js认为文件即模块,即一个文件是一个模块.单一文件一般只专注做一件事情,保证了代码的简洁性. 创建模块: ...
- Node.js之路【第二篇】Nodejs中的pip(NPM)&REPL
什么是NPM 在学Python的时候我们肯定会使用第三方模块或者编写模块供别人使用,我们有一个非常好用的pip来帮我们管理我们的模块包!那么Nodejs重的模块包呢? 对没错就是NPM,他是随同Nod ...
- 《唐三学node.js系列》—魂士篇&&三哥初始node.js
前言 如果你有一定的前端基础,比如 HTML.CSS.JavaScript.jQuery.那么Node.js 能让你以最低的成本快速过渡成为一个全栈工程师(我称这个全栈为伪全栈,我认为的全栈也要精通数 ...
- Node.js最新技术栈之Promise篇
前言 大家好,我是桑世龙,github和cnodejs上的i5ting,目前在天津创业,公司目前使用技术主要是nodejs,算所谓的MEAN(mongodb + express + angular + ...
- 一名全栈工程师Node.js之路-转
Node.js 全球现状 虽然 Node.js 在国内没有盛行,但据 StackOverflow 2016 年开发者调查,其中 node.js .全栈.JavaScript 相关的技术在多个领域(包括 ...
- Node.js写文件的三种方法
Node.js写文件的三种方式: 1.通过管道流写文件 采用管道传输二进制流,可以实现自动管理流,可写流不必当心可读流流的过快而崩溃,适合大小文件传输(推荐) var readStream = fs. ...
- Node.js 自学之旅(初稿篇)
学习基础,JQuery 原生JS有一定基础,有自己一定技术认知(ps:原型链依然迷糊中.闭包6不起来!哎!) 当然最好有语言基础,C#,java,PHP等等.. 最初学习这个东西的原因很简单,在园子里 ...
- Node.js 蚕食计划(三)—— Express 启航
如果看过上一篇<Node.js 蚕食计划>,就会发现手动搭建一个 web 服务器还是比较繁琐 而 express 就是一个可以极大地提高开发效率的 web 开发框架 一.创建项目 在 ex ...
随机推荐
- Event Handler
在Event Handler中,有一种特殊的Event Handler,称之为Synchronizer或者Denormalizer,其作用就是为了同步“Query Database”.Query Da ...
- iOS系列 基础篇 09 开关、滑块和分段控件
iOS系列 基础篇 09 开关.滑块和分段控件 目录: 案例说明 开关控件Switch 滑块控件Slider 分段控件Segmented Control 1. 案例说明 开关控件(Switch).滑块 ...
- 基于Spring+SpringMVC+Mybatis的Web系统搭建
系统搭建的配置大同小异,本文在前人的基础上做了些许的改动,重写数据库,增加依据权限的动态菜单的实现,也增加了后台返回json格式数据的配置,详细参见完整源码. 主要的后端架构:Spring+Sprin ...
- 【FLUENT案例】03:冲蚀
1 引子2 问题描述3 模型准备4网格5模型设置6 材料设置7 设定注入器8 修改材料9 Cell zone Conditions设置10 边界条件设置10.1 inlet入口设置10.2 出口设置1 ...
- input输入框的光标
上午的时候,以前一起配合Java后端的哥们问了个input光标的问题. 需求是这样:只能输入数字的input(一开始以为是输入金额这些的,后来才晓得是用来填写手机号) 他采用是直接百度来的如下方法: ...
- 项目自动化建构工具gradle 入门3——生一个exe的helloWorld
前两次呢,我们能够用一个外部的jar 来实现输出helloWorld.但问题是我每次都要用java -jar 来执行,这样我们自己玩还可以,让用户玩就不好了.所以我们生成一个exe给他们吧.这次我们仍 ...
- [No0000AD]7z源码完全移植至Visual Studio 2015
今天在上次的基础上(原文地址:[No0000AB]用Visual Studio 2015在 WIN10 64bit 上编译7-zip (32 bit)),将7Z的源码完全移植到了vs2015开发环境下 ...
- /var/log/messages
messages 该日志文件是许多进程日志文件的汇总,从该文件可以看出任何入侵企图或成功的入侵,包括整体系统信息,是系统最核心的日志.它包含了系统启动时的引导消息,以及系统运行时的其他状态消息.IO ...
- BZOJ 1415 【NOI2005】 聪聪和可可
题目链接:聪聪和可可 一道水题--开始还看错题了,以为边带权--强行\(O(n^3)\)预处理-- 首先,我们显然可以预处理出一个数组\(p[u][v]\)表示可可在点\(u\),聪聪在点\(v\)的 ...
- [LeetCode] Top K Frequent Elements 前K个高频元素
Given a non-empty array of integers, return the k most frequent elements. For example,Given [1,1,1,2 ...