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. MySql索引总结

    索引概念 B+树索引分为聚集索引和非聚集索引(辅助索引),但是两者的数据结构都和B+树一样,区别是存放的内容. 可以说数据库必须有索引,没有索引则检索过程变成了顺序查找,O(n)的时间复杂度几乎是不能 ...

  2. sql server 常用的扩展存储过程

    sql server 里面提供了丰富的系统存储过程来辅助我们管理数据库以及开发.今天分享介绍一些常用的数据库扩展存储过程 xp_cmdshell 这个大家都比较熟悉了,使用xp_cmdshell 可以 ...

  3. mysql初级命令

    修改本地mysql root密码 #mysqladmin -uroot -p原密码 password  现密码 #mysqladmin -uroot -p passwd  password nowwd ...

  4. spring3系列一

    IOC基础 Ioc是什么 Ioc--Inversion of Control 控制反转,不是什么技术,而是一种设计思想.在java开发中,ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对 ...

  5. 使用iTerm2快捷连接SSH

    iTerm2和Mac自带的Terminal差不多,但是功能更强大,无论透明度.字体.配色.分屏等都可以设置,除了这些花哨的功能外,最近新学了一招,就是可以通过Profiles的设置打开就执行写好的脚本 ...

  6. [原]CentOS7部署osm2pgsql

    转载请注明原作者(think8848)和出处(http://think8848.cnblogs.com) 部署Postgresql和部署PostGis请参考前两篇文章 本文主要参考GitHub上osm ...

  7. [LeetCode] Minimum Size Subarray Sum 最短子数组之和

    Given an array of n positive integers and a positive integer s, find the minimal length of a subarra ...

  8. [LeetCode] Populating Next Right Pointers in Each Node II 每个节点的右向指针之二

    Follow up for problem "Populating Next Right Pointers in Each Node". What if the given tre ...

  9. Zend Framework 项目 index.php 的问题

    默认生成的Zend项目在public目录下会自动生成一个.htaccess文件,这是用来实现伪静态,即隐藏index.php这个唯一入口文件的. 但是,搭建项目时遇到一个问题:URL中如果不加inde ...

  10. ie11的DOM管理器报错

    IE11 Windows7下F12 DOC资源管理器不能用Exception in window.onload: Error: An error has ocurredJSPlugin.3005--- ...