一个周末掌握IT前沿技术之node.js篇一:Node.js与javascript
Node.js is a platform built on Chrome’s JavaScript runtimefor easily building fast, scalable network applications.Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.
|
Node.js是一个服务器端 JavaScript 解释器,提供一种简单的构建可伸缩网络程序的方法,运行它的服务器能支持数万个并发连接。Node.js采用一种事件驱动的非阻塞I/O模型,可以在分布式系统上运行轻量级高性能的数据密集型实时应用。
|
一. JavaScript的 编程模型
Node.js的源代码是由它有8000行C++代码,2000行JavaScript代码构成。JavaScript 解析引擎 V8是 Google 发布的开源 JavaScript 引擎,采用 C++ 编写,在 Google 的 Chrome浏览器中被使用。V8 引擎可以独立运行,也可以用来嵌入到 C++ 应用程序中执行。
|
生存空间
|
地球(空气、水、阳光 ……)
|
你在哪?
|
接口
|
制造工具、改变环境、改变他人、改变自己
|
可以干什么?
|
行为
|
吃饭、泡妞、学习……
|
怎么干?
|
1.1. 生存空间。
1
|
<!doctype html>
|
[backcolor=rgb(248, 248, 248) !important]
2
|
<html>
|
3
|
<head>
|
[backcolor=rgb(248, 248, 248) !important]
4
|
<meta charset="utf-8">
|
5
|
<title>这是一个网页</title>
|
[backcolor=rgb(248, 248, 248) !important]
6
|
</head>
|
7
|
<body>
|
[backcolor=rgb(248, 248, 248) !important]
8
|
这是网页的内容
|
9
|
<div id ="testdiv"></div>
|
[backcolor=rgb(248, 248, 248) !important]
10
|
11
|
<script type="text/javascript" src="/static/js/test1.js"></script>
|
[backcolor=rgb(248, 248, 248) !important]
12
|
<script type="text/javascript" src="/static/js/test2.js"></script>
|
13
|
[backcolor=rgb(248, 248, 248) !important]
14
|
</body>
|
15
|
</html>
|
1
|
var testdiv = document.getElementById("testdiv");
|
[backcolor=rgb(248, 248, 248) !important]
2
|
for (var i = 0; i < 3; i++) {
|
3
|
var childDiv = document.createElement("div");
|
[backcolor=rgb(248, 248, 248) !important]
4
|
childDiv.appendChild(document.createTextNode("这是第"+i+"个子节点"));
|
5
|
testdiv.appendChild(childDiv);
|
[backcolor=rgb(248, 248, 248) !important]
6
|
}
|
7
|
var message="欢迎参加《一个周末掌握IT前沿技术》的极限学习活动!"
|
1
|
var childDiv = document.createElement("div");
|
[backcolor=rgb(248, 248, 248) !important]
2
|
childDiv.appendChild(document.createTextNode(message));
|
3
|
testdiv.appendChild(childDiv);
|
1
|
/**
|
[backcolor=rgb(248, 248, 248) !important]
2
|
* Date: 12-3-24
|
3
|
* 演示程序1
|
[backcolor=rgb(248, 248, 248) !important]
4
|
* 说明: 运行服务器,访问http://127.0.0.1
|
5
|
*/
|
[backcolor=rgb(248, 248, 248) !important]
6
|
var http = require("http");
|
7
|
var message = require("./demo1/message");
|
[backcolor=rgb(248, 248, 248) !important]
8
|
var i = 1;
|
9
|
[backcolor=rgb(248, 248, 248) !important]
10
|
http.createServer(
|
11
|
function (request, response) {
|
[backcolor=rgb(248, 248, 248) !important]
12
|
13
|
response.writeHead(200, {"Content-Type":"text/html; charset=UTF-8"});
|
[backcolor=rgb(248, 248, 248) !important]
14
|
15
|
response.write("欢迎您第" + i + "次访问服务器!<br>Welcome!"+message);
|
[backcolor=rgb(248, 248, 248) !important]
16
|
17
|
i++;
|
[backcolor=rgb(248, 248, 248) !important]
18
|
console.log("服务器访问被访问次数: i = " + i);
|
19
|
console.log(process.env);
|
[backcolor=rgb(248, 248, 248) !important]
20
|
response.end();
|
21
|
[backcolor=rgb(248, 248, 248) !important]
22
|
}).listen(80);
|
1
|
/**
|
[backcolor=rgb(248, 248, 248) !important]
2
|
* Date: 12-3-24
|
3
|
* 说明: 存放message
|
[backcolor=rgb(248, 248, 248) !important]
4
|
*/
|
5
|
var message = "欢迎参加《一个周末掌握IT前沿技术》的极限学习活动!";
|
[backcolor=rgb(248, 248, 248) !important]
6
|
module.exports = message;
|
1.2 接口。
题外讨论:《Web开发的复杂性》
由于web应用开发涉及到了现代计算结构中最复杂的两个部分:网络访问和显示, 比起Android,IOS,Windows平台开发,web应用的开发难度、学习成本往往都是最高的。网络开发之所以复杂,因为一个完整的网络应用往往都会涉及到各种网络通信流程(http/DNS/push/pull),连接形式(P2P/BS),网络结构(IPv4/IPv6/net/route),网络安全(SSL/DES/RSA/)等等内容。显示的开发,无论是PC端还是移动端,无论用何种程序语言表达,都被证明是一个复杂的过程。就以dom树驱动的网页显示为例,一个非常简单的网站往往都会有数千行的css代码来定义它的布局流样式。显示开发复杂的原因是显而易见的。当程序仅仅指定要将一个文字或图形显示在屏幕上时,浏览器需要计算出它在网页中的位置和样式并指定它的位图编码,然后通知操作系统;操作系统结合应用程序或intent(浏览器)的显示情况,确定位图在屏幕中的显示,然后调用显示框架,或直接通知显卡;显卡根据指示计算位图的边界、旋转、透明处理、覆盖…等等,最后算出一块数据更新显存buffer,当显存buffer切换时,屏幕上才会出现程序指定的那个文字或图形。
下面的JS代码可以在屏幕上绘制“测试文字”4个字符:
[backcolor=rgb(255, 255, 255) !important]
[backcolor=rgb(248, 248, 248) !important]
[backcolor=rgb(248, 248, 248) !important]
[backcolor=rgb(248, 248, 248) !important]
[backcolor=rgb(248, 248, 248) !important]
[backcolor=rgb(248, 248, 248) !important]
[backcolor=rgb(248, 248, 248) !important]
[backcolor=rgb(255, 255, 255) !important]
对于显示内容的输入事件的处理过程则更为复杂。以Windows系统鼠标点击浏览器上某个位置为例。鼠标按下,ring0层检测到usb硬件中断,硬件中断形成的句柄随着硬件树向上传播处理,直到被识别为一个“鼠标按下”的事件;“鼠标按下”的事件带着坐标等等参数传给了ring3层,进入windows消息循环;windows消息循环分析得知该事件应该传给chrome浏览器处理;chrome浏览器MFC的消息循环接到windows传来的消息,分析处理后,又将其传给webkit;webkit的消息循环顺着dom树将消息向下传播,确定对应的节点;webkit分析对应节点的“鼠标按下”事件有没有被JS V8引擎注册了回调函数;如果有则将事件参数传给该回调函数处理。
从上面的分析我们可以发现,太多的层级关系太多的循环使得人类和计算机程序的交流相隔千山万水。真正完美的产品需要将这些复杂度完美地隐藏起来,给用户展现的是一种人性的交流。这个矛盾正是导致web开发复杂性的根源。
优秀的工具(包括协议和编程语言)正是为了降低这个复杂性而在不懈地努力。在这些努力的实践中我们渐渐地发现,我们需要的是更优秀的协议,而不是一层一层堆积起来的框架。由于历史的原因,HTML技术背负了太多沉重的包袱,这使得web技术发展的没有希望的那么快。HTML5依然如此,你绝对不可能通过HTML5技术写出一个“极品飞车”这样的流畅的游戏。虽然目前HTMl5技术已经展现出对客户端进行挑战的潜力,从界面的表现和渲染方式、与桌面的交互处理、多线程并行处理、本地离线存储、访问本地硬件资源等多个能力上都有较为成熟的技术方案,但是HTML的文档流式布局只适合浏览报纸,不太适合web应用。即使如此,人们对于技术进步的努力从来没有停止。如果你现在也在思考着这些问题,那么你也是其中之一。或许我们可以期待脱离浏览器的canvas.js或WebGL.js的出现,或许我们的设备会进步到有颠覆性的技术产生。再或许我们的文明不再需要计算机科学。
|
1.3 行为。
学习JavaScript语言结构,我们一定要摆脱传统面向对象语言思维习惯的干扰。传统面向对象,既有对象的类,也有对象的实例。JavaScript只有对象的实例,没有类。如果我们熟悉python语言,分析下面这段代码:
1
|
class A(object):
|
[backcolor=rgb(248, 248, 248) !important]
2
|
b1=[1,2,3,4]
|
3
|
b2="这是字符串"
|
[backcolor=rgb(248, 248, 248) !important]
4
|
def b3(self):
|
5
|
print("这是一个函数")
|
[backcolor=rgb(248, 248, 248) !important]
6
|
7
|
a=A()
|
[backcolor=rgb(248, 248, 248) !important]
8
|
a.b3()#屏幕输出"这是一个函数"
|
请分析下面这段代码instance.js:这是全篇最重要的一个例程,一定要上机实践,分析清楚它的每一行代码。
1
|
var a = {
|
[backcolor=rgb(248, 248, 248) !important]
2
|
b1 : {
|
3
|
c1 : [1, 2, 3, 4]//这是数组
|
[backcolor=rgb(248, 248, 248) !important]
4
|
},
|
5
|
b2 : "这是字符串"
|
[backcolor=rgb(248, 248, 248) !important]
6
|
};
|
7
|
console.log(JSON.stringify(a)); //log输出为{"b1":{"c1":[1,2,3,4]},"b2":"这是字符串"}
|
[backcolor=rgb(248, 248, 248) !important]
8
|
a.b3 = function () {
|
9
|
console.log("这是一个函数");
|
[backcolor=rgb(248, 248, 248) !important]
10
|
};
|
11
|
console.log(JSON.stringify(a)); //log输出仍然为{"b1":{"c1":[1,2,3,4]},"b2":"这是字符串"}
|
[backcolor=rgb(248, 248, 248) !important]
12
|
a.b1.c2 = a;
|
13
|
console.log(JSON.stringify(a)); //log输出"TypeError: Converting circular structure to JSON",提示有循环的结构是不能被字符串化的。
|
[backcolor=rgb(248, 248, 248) !important]
14
|
d=JSON.parse('{"b1":{"c1":[1,2,3,4]},"b2":"这是字符串"}');
|
15
|
console.log(a==d);//log输出false
|
[backcolor=rgb(248, 248, 248) !important]
16
|
console.log(a.b1==d.b1);//log输出false
|
17
|
console.log(a.b2==d.b2);//log输出true
|
JavaScript的闭包性深受人们的赞誉也深受人们的反对。对于初学者,闭包性会带来变量命名空间的混乱。然而它是一种非常优秀的变量空间模型。还记得C++里面的”using namespace XXX;”这样的语句吧?它可以使一段c++代码访问另一段代码的变量、函数和类。
JavaScript的闭包性(closure)就是:让函数在运行时能够访问到函数定义时的所处作用域内的所有变量。函数定义时能访问到什么变量,那么在函数运行时通过相同的变量名一样能访问到。我们分析如下代码:
1
|
/**
|
[backcolor=rgb(248, 248, 248) !important]
2
|
* Date: 12-3-24
|
3
|
*
|
[backcolor=rgb(248, 248, 248) !important]
4
|
* 说明: 这个例程说明闭包性和回调函数的原理
|
5
|
* 执行程序的输出如下:
|
[backcolor=rgb(248, 248, 248) !important]
6
|
**这是函数a.c()
|
7
|
**这是字符串: 是一个字符串
|
[backcolor=rgb(248, 248, 248) !important]
8
|
**这是局部函数inner()
|
9
|
**这是函数a.d(callback)
|
[backcolor=rgb(248, 248, 248) !important]
10
|
**这是匿名函数
|
11
|
**这是函数a.e(string)
|
[backcolor=rgb(248, 248, 248) !important]
12
|
**变量string是: 这是字符串
|
13
|
*/
|
[backcolor=rgb(248, 248, 248) !important]
14
|
15
|
var a = {
|
[backcolor=rgb(248, 248, 248) !important]
16
|
b : "这是字符串"
|
17
|
};
|
[backcolor=rgb(248, 248, 248) !important]
18
|
19
|
a.c = function () {
|
[backcolor=rgb(248, 248, 248) !important]
20
|
console.log("这是函数a.c()");
|
21
|
console.log(this.b + ": 是一个字符串");
|
[backcolor=rgb(248, 248, 248) !important]
22
|
var b = this.b;
|
23
|
inner(this.d);
|
[backcolor=rgb(248, 248, 248) !important]
24
|
function inner(callback) {
|
25
|
console.log("这是局部函数inner()");
|
[backcolor=rgb(248, 248, 248) !important]
26
|
callback(function () {
|
27
|
console.log("这是匿名函数");
|
[backcolor=rgb(248, 248, 248) !important]
28
|
a.e(b); //这里的匿名函数可以访问到函数a.c()中定义的变量b;a是全局对象。
|
29
|
});
|
[backcolor=rgb(248, 248, 248) !important]
30
|
};
|
31
|
};
|
[backcolor=rgb(248, 248, 248) !important]
32
|
33
|
a.d = function (callback) {
|
[backcolor=rgb(248, 248, 248) !important]
34
|
console.log("这是函数a.d(callback)");
|
35
|
callback()
|
[backcolor=rgb(248, 248, 248) !important]
36
|
};
|
37
|
[backcolor=rgb(248, 248, 248) !important]
38
|
a.e = function (string) {
|
39
|
console.log("这是函数a.e(string)");
|
[backcolor=rgb(248, 248, 248) !important]
40
|
console.log("变量string是: " + string);
|
41
|
};
|
[backcolor=rgb(248, 248, 248) !important]
42
|
a.c();
|
与JavaScript的闭包性深受人们的赞誉不同,对JavaScript的回调函数却是承受着更多的批评。回调函数,匿名回调函数,特别是嵌套匿名回调函数,是造成代码逻辑混乱的主要原因,也是大型JavaScript项目的代码可读性很差的原因。如果我们能够清晰地理解上面例程中”匿名函数“被调用的机制,那么JavaScript的回调函数就被我们掌握了。JavaScript的回调函数可以帮助我们更方便地实现异步逻辑,它的实现机理其实就是函数指针。如果阅读windows源代码,可以发现它的各种异步逻辑处理比如说消息循环,都是通过传递句柄也就是函数指针来实现。
既然提到了消息循环,我们就来分析一下JavaScript的事件机制。Node.js和webkit都采用的是一种事件驱动的非阻塞I/O模型。为什么使用单线程的Node.js可以提供高速的并发能力?实际上著名Nginx也是基于单线程的。对于Nginx,我们后面的内容将会详细讲到。不像Apache+PHP那样派生出很多的OS线程来解决并发的问题,Node.js只有1个线程轮询它周围发生的各个事件。而每个事件的”发生“和”处理“过程却和这个线程无关。这个线程只负责查看某个事件是不是已经”发生“了,如果”发生“了,就通知与事件相应的回调函数慢慢”处理“这个事件。轮询线程不会等待这个事件的”处理“过程,它只是通知一下,紧接着查看其它事件的”发生“状态。事件本质上一个时空不一致的非线性模型,或所谓的“异步(Asynchronization)”。事件发生的顺序按照外界对其发出的时刻而确定,有的在先,有的在后,有时也可以齐头并进,一起同时触发,结束时也可以快的快、慢的慢。为了加速Node.js对于网络的并发访问,在实现上Node.js采用了epoll技术。对于webkit事件引擎的机制也是类似,这不过它处理的对象不是网络事件,更多的是dom树上的用户操作,这不需要太多关注并发性能。这也就是Node.js出现以前,对于JavaScript事件引擎人们关注不多的原因。不管是服务端还是客户端JavaScript我们都需要理解,事件引擎+回调函数构成了JavaScript运行模型。
除了对象,一些JavaScript的内置数据结构,比如说字符串(string),数组(array),正则表达式(RegExp),可以大大方便我们程序逻辑的实现。对于有对象颗粒的数据结构,JavaScript内置的迭代器可以让我们的程序逻辑更加清晰明了。请看下面一段代码iterator.js,这是本章的最后一个例程,请大家思考程序的输出会是什么?
1
|
/**
|
[backcolor=rgb(248, 248, 248) !important]
2
|
* Date: 12-3-24
|
3
|
*
|
[backcolor=rgb(248, 248, 248) !important]
4
|
* 说明: 这个例程说明迭代器的使用
|
5
|
*/
|
[backcolor=rgb(248, 248, 248) !important]
6
|
7
|
var a = {
|
[backcolor=rgb(248, 248, 248) !important]
8
|
a1 : "这是字符串a1",
|
9
|
a2 : "这是字符串a2",
|
[backcolor=rgb(248, 248, 248) !important]
10
|
b : {
|
11
|
b1 : "这是字符串b1",
|
[backcolor=rgb(248, 248, 248) !important]
12
|
b2 : "这是字符串b2",
|
13
|
b3 : "这是字符串b3",
|
[backcolor=rgb(248, 248, 248) !important]
14
|
b4 : "这是字符串b4",
|
15
|
c : {
|
[backcolor=rgb(248, 248, 248) !important]
16
|
c1 : "这是字符串c1",
|
17
|
c2 : "这是字符串c2",
|
[backcolor=rgb(248, 248, 248) !important]
18
|
d : {
|
19
|
d1 : "这是字符串d1",
|
[backcolor=rgb(248, 248, 248) !important]
20
|
d2 : "这是字符串d2",
|
21
|
}
|
[backcolor=rgb(248, 248, 248) !important]
22
|
},
|
23
|
}
|
[backcolor=rgb(248, 248, 248) !important]
24
|
};
|
25
|
[backcolor=rgb(248, 248, 248) !important]
26
|
function showContent(a, path) {
|
27
|
for (key in a) {//迭代器
|
[backcolor=rgb(248, 248, 248) !important]
28
|
var child = a[key];
|
29
|
if (typeof(child) == "string") {
|
[backcolor=rgb(248, 248, 248) !important]
30
|
console.log("变量'" + path + "." + key + "'的值是: " + child);
|
31
|
} else {
|
[backcolor=rgb(248, 248, 248) !important]
32
|
showContent(child, (path + "." + key));//递归遍历树形数据结构。
|
33
|
}
|
[backcolor=rgb(248, 248, 248) !important]
34
|
35
|
}
|
[backcolor=rgb(248, 248, 248) !important]
36
|
};
|
37
|
[backcolor=rgb(248, 248, 248) !important]
38
|
showContent(a, "a");
|
c++ |
JavaScript
|
|
对象模型
|
继承
|
对象组合
|
变量空间模型
|
封装
|
闭包
|
运行时模型
|
多态
|
迭代器、回调函数、事件引擎
|
一个周末掌握IT前沿技术之node.js篇一:Node.js与javascript相关推荐
- 对话数十位学术合作代表:如何提升前沿技术在商业领域的落地应用?
从去年火出天际的元宇宙,到今年年初的现象级应用 ChatGPT,科技圈似乎从不缺少热门的技术概念与话题.尤其是在云计算.人工智能.大数据等技术呈爆发式增长的背景下,我们愈发体会到前沿技术对于产业产生的 ...
- AI:2023年6月9日北京智源大会演讲分享之基础模型前沿技术论坛—《工程化打造AI中的CPU》、《构建一个AI系统:在LLM上应用带有RLHF来推进定制》、《多模态预训练的进展回顾与展望》、《扩展大
AI:2023年6月9日北京智源大会演讲分享之基础模型前沿技术论坛-<工程化打造AI中的CPU>.<构建一个AI系统:在LLM上应用带有RLHF来推进定制>.<多模态预训 ...
- 总结之知识图谱前沿技术课程
前言 正文 参考文献 前言 写在前面,本文的内容主要基于2017年12月2日在苏州大学举办的知识图谱前沿技术课程(感谢各位老师的talk,受益良多)以及本人在之前阅读的有关paper,对KG和QA ...
- 会议学习笔记(一):第十五届《前沿技术讲习班》之唐建
第十五届中国中文信息学会暑期学校暨中国中文信息学会<前沿技术讲习班>的回放链接:http://conference.cipsc.org.cn/ssatt2020/ 学习笔记 唐建:Neur ...
- AutoML前沿技术与实践经验分享 | 免费公开课
传统机器学习的解决范式可表示为: ML Solution = ML expertise + Computation + Data 新机器学习范式可表示为: New ML Solution = 100x ...
- AutoML前沿技术与实践经验分享 | 免费报名
传统机器学习的解决范式可表示为: ML Solution = ML expertise + Computation + Data 新机器学习范式可表示为: New ML Solution = 100x ...
- 2020北京智源大会人工智能前沿技术成果征集
2020北京智源大会面向全球征集高校院所.科研机构或企业的人工智能前沿技术成果,通过遴选的成果将在大会官网进行长期专栏展示和推介. 征集要求 征集时间:2020.05.27-2020.06.15 征集 ...
- 马歇尔·赫伯特:人工智能的前沿技术与实例分析
来源:中国人工智能学会 2017年12月11日,国际知名机器人专家.美国卡耐基梅隆大学机器人研究所所长马歇尔·赫伯特(Martial Hebert)教授和首席科学家大卫·伯恩(David Bourne ...
- “我只需一个周末就可以构建出这个应用!”
作者 | JOÃO ALVES 译者 | 弯月 出品 | CSDN(ID:CSDNnews) 以下为译文: 每次人们购买新房.新车或新电视时,都会对新买的产品赞不绝口,这时他们与新买的产品还处于 ...
- 图像处理、语音处理的应用及前沿技术_人工智能,虚拟技术,语音识别技术在我们的生活中...
人工智能(Artificial Intelligence),英文缩写为AI.它是研究.开发用于模拟.延伸和扩展人的智能的理论.方法.技术及应用系统的一门新的技术科学. 人工智能是计算机科学的一个分支, ...
最新文章
- python语言只采用解释一种翻译方式对吗_python-guide翻译
- Ubuntu16.04 LTS上安装Go1.10
- avisynth_c.h:825:3: error: unknown type name ‘HMODULE’
- CSS的子选择器与后代选择器的区别
- 世界顶级的程序员们告诉你:这些书都是你应该读的
- Tomcat 发布项目 conf/Catalina/localhost 配置 及数据源配置
- 草稿 断开式的连接 1127
- 新DELL服务器在F2设置界面下raid的配置
- mysql查看enum和set值_mysql中的enum和set类型_MySQL
- 实验——示波器法测量相位差(试验记录)
- 学生宿舍管理系统需求分析
- jenkins构建时报错ERROR: Cannot run program “docker“ (in directory “/var/jenkins_home/workspace/
- D盘或者E盘根目录出现msdia80.dll文件的解决方法
- 电脑软件:推荐一款磁盘空间分析工具——WizTree
- lvgl v8之Styling the scrollbars
- 计算机网络-自顶向下方法 读书笔记
- shiro权限框架中五张基本数据表
- 三星Q950T全景声回音壁测试心得
- 前端开发Vue项目实战:电商后台管理系统(八)------ 订单管理模块
- android 永久root权限,安卓 实现永久性开启adb 的root权限
热门文章
- Win10台式电脑怎么不拔网线断网
- excel两列数据对比找不同_Excel两组数据做对比,用左右对比图才好看,操作简单又美观...
- linux 检查系统丢包,Linux 下网络丢包问题处理
- 计算机检索高考投档线,投档分数线是什么意思 低于投档线会被录取吗
- Android KeyStore的使用
- [Loj 6070][回文树+可持久化线段树+border理论]基因
- 画图软件origin-柱状图断点设置
- arcgis api for javascript 3.33 清空、删除图层
- 2019年阿里巴巴暑期实习面经--数据研发工程师--口碑
- 读书笔记:时间与精力管理:拖延症与六种效应