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异步实现的更多相关文章

  1. Node.js之路【第一篇】初识Node.js

    什么是Node.js 1.Node.js就是运行在服务端的JavaScrip. 2.Node.js是一个基于Chrome JavaScrip运行时简历的一个平台. 3.Node.js是一个非阻塞I/O ...

  2. Node.js入门教程 第三篇 (模块及路由)

    Node.js的模块 Node.js的模块与传统面向对象的类(class)不完全相同.Node.js认为文件即模块,即一个文件是一个模块.单一文件一般只专注做一件事情,保证了代码的简洁性. 创建模块: ...

  3. Node.js之路【第二篇】Nodejs中的pip(NPM)&REPL

    什么是NPM 在学Python的时候我们肯定会使用第三方模块或者编写模块供别人使用,我们有一个非常好用的pip来帮我们管理我们的模块包!那么Nodejs重的模块包呢? 对没错就是NPM,他是随同Nod ...

  4. 《唐三学node.js系列》—魂士篇&&三哥初始node.js

    前言 如果你有一定的前端基础,比如 HTML.CSS.JavaScript.jQuery.那么Node.js 能让你以最低的成本快速过渡成为一个全栈工程师(我称这个全栈为伪全栈,我认为的全栈也要精通数 ...

  5. Node.js最新技术栈之Promise篇

    前言 大家好,我是桑世龙,github和cnodejs上的i5ting,目前在天津创业,公司目前使用技术主要是nodejs,算所谓的MEAN(mongodb + express + angular + ...

  6. 一名全栈工程师Node.js之路-转

    Node.js 全球现状 虽然 Node.js 在国内没有盛行,但据 StackOverflow 2016 年开发者调查,其中 node.js .全栈.JavaScript 相关的技术在多个领域(包括 ...

  7. Node.js写文件的三种方法

    Node.js写文件的三种方式: 1.通过管道流写文件 采用管道传输二进制流,可以实现自动管理流,可写流不必当心可读流流的过快而崩溃,适合大小文件传输(推荐) var readStream = fs. ...

  8. Node.js 自学之旅(初稿篇)

    学习基础,JQuery 原生JS有一定基础,有自己一定技术认知(ps:原型链依然迷糊中.闭包6不起来!哎!) 当然最好有语言基础,C#,java,PHP等等.. 最初学习这个东西的原因很简单,在园子里 ...

  9. Node.js 蚕食计划(三)—— Express 启航

    如果看过上一篇<Node.js 蚕食计划>,就会发现手动搭建一个 web 服务器还是比较繁琐 而 express 就是一个可以极大地提高开发效率的 web 开发框架 一.创建项目 在 ex ...

随机推荐

  1. Unity、c#中的拓展方法讲解

    很早以前看过这个东西,但是没有真正的用到过,希望之后会用到上面的方法, 大概的意思是这样的c#中尤其在用Unity的时候,已有的框架提供给我们一些固定的方法,但是有时我们想对这些方法进行修改, 这时我 ...

  2. java中 String StringBuffer StringBuilder的区别

    * String类是不可变类,只要对String进行修改,都会导致新的对象生成. * StringBuffer和StringBuilder都是可变类,任何对字符串的改变都不会产生新的对象. 在实际使用 ...

  3. 开窗函数 First_Value 和 Last_Value

    在Sql server 2012里面,开窗函数丰富了许多,其中带出了2个新的函数 First_Value 和 Last Value .现在来介绍一下这2个函数的应用场景. 首先分析一下First_Va ...

  4. Python常用方法

    Python strip()方法 描述: Python strip()方法用于移除字符串头尾指定的字符(默认为空格). 语法: str.strip([chars]) 参数: chars -- 移除字符 ...

  5. sublime text 3 快捷键大全以及配置编译环境

    Sublime text 3是码农最喜欢的代码编辑器,每天和代码打交道,必先利其器,掌握基本的代码编辑器的快捷键,能让你打码更有效率.刚开始可能有些生疏,只要花一两个星期坚持使用并熟悉这些常用的快捷键 ...

  6. mdadm设定RAID磁盘阵列,且当分区故障后如何重建

    首先,fdisk建立不同分区,且设为fd格式 其次, mdadm -C md0 -a yes -l -n /dev/sda1 /dev/sdb1 /dev/sdc1 /dev/sdd1 /dev/sd ...

  7. jquery基础

    show() hide() toggle()         fadeIn() fadeOut() fadeToggle() fadeTo()         slideUp() slideDown( ...

  8. ubuntu kylin 14.04安装搜狗输入法

    1.卸载原有的输入法,fcitx或ibus.如卸载fcitx: sudo apt-get remove fcitx*(如不需保留配置文件用purge) sudo apt-get autoremove( ...

  9. ongl(原始类型和包装类型)

    原始类型和包装类型 //首先创建两个实体类 user 和 address user中包含address package cn.jbit.bean; public class User { //用户类 ...

  10. jenkins / ant / jmeter 持续集成接口自动化

    1. 将 jmeter 脚本放在/var/lib/jenkins/workspace/Jmeter_auto/jmxpath路径下 2. 点击http://jk.facebank.net.cn/job ...