Node.js开发者必须了解的4个JS要点


Posted in Javascript onFebruary 21, 2016

本文为开发者总结了4个Node.js要点。

1. 非阻塞(Non-blocking)或异步I/O

由于Node.js一个服务器端框架,所以它主要工作之一是处理浏览器请求。在传统的I/O系统中,每个请求的发出都是在上一请求到达之后才发出的。所以这被称为阻塞(blocking)I/O。服务器会阻挡其它的请求以处理当前请求,从而导致浏览器等待。

Node.js不以这种方式来进行I/O处理。如果一个请求需要长时间处理,Node.js会把该请求发送给一个事件循环(event loop),然后继续处理在调用堆栈(call stack)中的下一请求。当延后请求处理完毕时,它会告知Node.js同时浏览器会做出响应反馈。

以下使用一个事例来说明。

Blocking I/O

// take order for table 1 and wait...
var order1 = orderBlocking(['Coke', 'Iced Tea']);
// once order is ready, take order back to table.
serveOrder(order1);
// once order is delivered, move on to another table.
// take order for table 2 and wait...
var order2 = orderBlocking(['Coke', 'Water']);
// once order is ready, take order back to table.
serveOrder(order2);
// once order is delivered, move on to another table.
// take order for table 3 and wait...
var order3 = orderBlocking(['Iced Tea', 'Water']);
// once order is ready, take order back to table.
serveOrder(order3);
// once order is delivered, move on to another table.

在这个餐馆例子中,服务员接收了菜单指令,等待饭菜处理,然后在饭菜处理完成后把饭菜端到桌子上。在服务员等候饭菜处理期间,他会拒绝其它客人的菜单指令。

Non-blocking I/O

// take order for table 1 and move on...
orderNonBlocking(['Coke', 'Iced Tea'], function(drinks){
 return serveOrder(drinks);
});
// take order for table 2 and move on...
orderNonBlocking(['Beer', 'Whiskey'], function(drinks){
 return serveOrder(drinks);
});
// take order for table 3 and move on...
orderNonBlocking(['Hamburger', 'Pizza'], function(food){
 return serveOrder(food);
});

而在非阻塞模式下,服务员会告知厨师他接受到的菜单指令,然后去接收下一桌的指令。当第一桌饭菜处理完毕时,他会为那桌客人上菜,然后继续接收其它客人的指令。这样一来服务员不会由于阻塞指令而造成时间浪费。

2. 原型(Prototype)

原型在JS中是一个复杂的概念。在典型继承机制语言如Java或C++中,为了实现代码复用,你必须先创建一个类然后透过它来生成对象或透过类扩展来生成对象。但是在JS中没有类似的类概念。在JS中创建一个对象后,你需要透过它来扩展对象或创建新对象。这就叫做原型继承(prototypal inheritence)。

每个JS对象都连接着一个原型对象并对并继承该对象的属性。每个对象与预定义JS的Object.prototype相联系。如果你透过obj.propName或obj[‘propName'>方式来查找对象属性但查找失败时,这时可尝试通过obj.hasOwnProperty(‘propName')的方式进行查找,JS运行时会在在原型对象中查找属性。如果属性不存在于原型链中,那么将返回undefined值。

让我们用以下例子来进行说明:

if (typeof Object.create !== 'function') {
  Object.create = function (o) {
    var F = function () {};
    F.prototype = o;
    return new F();
  };
var otherPerson = Object.create(person);

当你创建了一个新对象,你必须选定一个以原型为基础的对象。在这里,我们为对象函数添加了一个create方法。create方法创建了一个以其它对象为原型的对象,并作为参数传入。

当我们变更新的对象时,它的原型是保持不变的。但是,当我们改动了原型对象,该变更会影响所有基于该原型的对象。

3. 组件(Modules)

如果你曾在Java中使用过包,那么Node.js的组件与之类似。如果没有,也不用担心;组件其实是简单的JS文件,用于实现特定的功能。组件模式的意义是让你工作得更加轻松。要使用组件,你必须像在JAVA中导入包一样进行JS文件导入。Node.js中有两种组件

核心组件(Core Modules)- 核心组件是结合Node.js库被预编译的。其目的是把程序员经常使用的功能开放出来,避免重复劳动。常见的核心组件有HTTP, URL, EVENTS, FILE SYSTEM等等。

用户自定义组件(UserDefined Modules)- 用户自定义组件是提供给用户使用以实现具体功能的组件。当核心组件不足以满足程序员需要的时候,自定义组件就可派上用场了。

组件是通过require函数被抽取的。如果这是一个核心组件,那么参数就是组件名。如果这是一个用户自定义组件,那么参数就是其在文件系统中的组件路径。例如:

// extract a core module like this
var http = require('http);
// extract a user defined module like this
var something = require('./folder1/folder2/folder3/something.js');

4. 回调(Callbacks)

在JS中,函数是第一类对象。也就是说你可以像对常规对象那样对函数进行所有操作。例如指派函数到一个变量,把这些作为参数传给方法,把它们声明为对象的属性,甚至是把它们从函数里返回。

回调在JS中是异步函数,可以作为参数传递给其它函数或从其它函数里执行或返回而后再执行。这是回调的基本概念。

当我们把一个回调函数作为参数传递给另外的函数时,我们传递的仅仅是函数的定义;换言之,我们不会知道回调函数的执行时间。这完全依赖于回调函数机制。它会在稍后某个时间点进行回调调用。这是Node.js的非阻塞或异步行为的基本概念,可用下例进行说明:

setTimeout(function() {
  console.log("world");
}, 2000)
console.log("hello");

这是一个最简单的调用。我们把一个匿名函数作为参数进行传递,作用是为setTimeout函数进行控制台的输出记录登记。因为这仅仅是个函数定义,我们不知道函数何时会被执行。这取决于setTimeout函数的second参数,即2S后。

首先,second记录语句记录了对控制台的输出,2S后,在回调函数中的记录语句记录了输出的内容。

// output
hello
world

写在最后

以上4点对Node.js开发者来说是要彻底理解和掌握的,建议多动手来好好体会这4个要点的含义。

Javascript 相关文章推荐
js实现温度计时间样式代码分享
Aug 21 Javascript
javascript截图 jQuery插件imgAreaSelect使用详解
May 04 Javascript
jQuery实现动态文字搜索功能
Jan 05 Javascript
js获取当前周、上一周、下一周日期
Mar 19 Javascript
微信小程序中显示html格式内容的方法
Apr 25 Javascript
React-router 4 按需加载的实现方式及原理详解
May 25 Javascript
JavaScript实现多叉树的递归遍历和非递归遍历算法操作示例
Feb 08 Javascript
vue中锚点的三种方法
Jul 06 Javascript
layui中table表头样式修改方法
Aug 15 Javascript
使用weixin-java-miniapp配置进行单个小程序的配置详解
Mar 29 Javascript
Vue项目中使用jquery的简单方法
May 16 jQuery
Vue使用Clipboard.JS在h5页面中复制内容实例详解
Sep 03 Javascript
JSON简介以及用法汇总
Feb 21 #Javascript
javascript实现计时器的简单方法
Feb 21 #Javascript
JS中Eval解析JSON字符串的一个小问题
Feb 21 #Javascript
浏览器检测JS代码(兼容目前各大主流浏览器)
Feb 21 #Javascript
gameboy网页闯关游戏(riddle webgame)--仿微信聊天的前端页面设计和难点
Feb 21 #Javascript
全面详细的jQuery常见开发技巧手册
Feb 21 #Javascript
完善的jquery处理机制
Feb 21 #Javascript
You might like
建立文件交换功能的脚本(二)
2006/10/09 PHP
SSI指令
2006/11/25 PHP
php 购物车的例子
2009/05/04 PHP
一个典型的PHP分页实例代码分享
2011/07/28 PHP
php更新mysql后获取影响的行数发生异常解决方法
2013/03/28 PHP
ThinkPHP实现更新数据实例详解(demo)
2016/06/29 PHP
PHP实现带进度条的Ajax文件上传功能示例
2019/07/02 PHP
jquery的ajax从纯真网(cz88.net)获取IP地址对应地区名
2009/12/02 Javascript
jQuery页面滚动浮动层智能定位实例代码
2011/08/23 Javascript
js导出txt示例代码
2014/01/14 Javascript
jquery选择器大全 全面详解jquery选择器
2014/03/06 Javascript
jquery数组过滤筛选方法grep()简介
2014/06/06 Javascript
AngularJS基础学习笔记之简单介绍
2015/05/10 Javascript
JavaScript判断表单中多选框checkbox选中个数的方法
2015/08/17 Javascript
JS+CSS实现自适应选项卡宽度的圆角滑动门效果
2015/09/15 Javascript
jquery获取css的color值返回RGB的方法
2015/12/18 Javascript
Javascript 5种方法实现过滤删除前后所有空格
2016/06/22 Javascript
仿Angular Bootstrap TimePicker创建分钟数-秒数的输入控件
2016/07/01 Javascript
Angular 4依赖注入学习教程之Injectable装饰器(六)
2017/06/04 Javascript
jquery+css实现下拉列表功能
2017/09/03 jQuery
手动用webpack搭建第一个ReactApp的示例
2018/04/11 Javascript
vuejs+element UI table表格中实现禁用部分复选框的方法
2019/09/20 Javascript
VUE渲染后端返回含有script标签的html字符串示例
2019/10/28 Javascript
Windows下将Python文件打包成.EXE可执行文件的方法
2018/08/03 Python
对python3 Serial 串口助手的接收读取数据方法详解
2019/06/12 Python
OpenCV 模板匹配
2019/07/10 Python
Python3安装pip工具的详细步骤
2019/10/14 Python
pytorch实现建立自己的数据集(以mnist为例)
2020/01/18 Python
python scatter函数用法实例详解
2020/02/11 Python
python isinstance函数用法详解
2020/02/13 Python
Python sklearn中的.fit与.predict的用法说明
2020/06/28 Python
解决Firefox下不支持outerHTML问题代码分享
2014/06/04 HTML / CSS
学校课外活动总结
2014/05/08 职场文书
详解MySQL InnoDB存储引擎的内存管理
2021/04/08 MySQL
python使用matplotlib绘制图片时x轴的刻度处理
2021/08/30 Python
了解MySQL查询语句执行过程(5大组件)
2022/08/14 MySQL