Nodejs为什么选择javascript为载体语言


Posted in NodeJs onJanuary 13, 2015

我们先来看看NodeJS官网上的介绍:

Nodejs为什么选择javascript为载体语言

其特点为:

1,它是一个Javascript运行环境

2,依赖于Chrome V8引擎进行代码解释

3,事件驱动

4, 非阻塞I/O

5, 轻量、可伸缩,适于实时数据交互应用

6,单进程,单线程

(1),Nodejs为什么选择javascript为载体语言

事实上,在实现 Node.js 之初,作者 Ryan Dahl 并没有选择 JavaScript,他尝试过 C、Lua,皆因其欠缺一些高级语言的特性,如闭包、函数式编程,致使程序复杂,难以维护。

而 JavaScript 则是支持函数式编程范型的语言,很好地契合了 Node.js 基于事件驱动的编程模型。加之 Google 提供的 V8 引擎,使 JavaScript 语言的执行速度大大提高。

最终呈现在我们面前的就成了 Node.js,而不是 Node.c,Node.lua 或其他语言的实现。

(2),Node.js不是JS应用、而是JS运行平台

看到Node.js这个名字,初学者可能会误以为这是一个Javascript应用,事实上,Node.js采用C++语言编写而成,是一个Javascript的运行环境。

Node.js采用了Google Chrome浏览器的V8引擎,性能很好,同时还提供了很多系统级的API,如文件操作、网络编程等。

以下是NodeJS所涉及的全部模块:

Nodejs为什么选择javascript为载体语言Nodejs为什么选择javascript为载体语言

浏览器端的Javascript代码在运行时会受到各种安全性的限制,对客户系统的操作有限。

相比之下,Node.js则是一个全面的后台运行时,为Javascript提供了其他语言能够实现的许多功能。

(3),Node.js的特点

Node.js在设计上也是比较创新,它以单进程,单线程模式运行(这和Javascript的运行方式是一致的),

事件驱动机制是Node.js通过内部单线程高效率地维护事件循环队列来实现的,没有多线程的资源占用和上下文切换,这意味着面对大规模的http请求,Node.js凭借事件驱动搞定一切,

习惯了传统语言的网络服务开发人员可能对多线程并发和协作非常熟悉,但是面对Node.js,我们需要接受和理解它的特点。

二,重要概念

1,什么是 Event Loop ?(很重要的概念)

Event Loop 是一个很重要的概念,指的是计算机系统的一种运行机制。

想要理解Event Loop,就要从程序的运行模式讲起。运行以后的程序叫做进程(Process),一般情况下,一个进程一次只能执行一个任务。

如果有很多任务需要执行,不外乎三种解决方法。

(1),排队。因为一个进程一次只能执行一个任务,只好等前面的任务执行完了,再执行后面的任务。

(2),新建进程。使用fork命令,为每个任务新建一个进程。

(3),新建线程。因为进程太耗费资源,所以如今的程序往往允许一个进程包含多个线程,由线程去完成任务。

以JavaScript语言为例,它是一种单线程语言,所有任务都在一个线程上完成,即采用上面的第一种方法。一旦遇到大量任务或者遇到一个耗时的任务,网页就会出现"假死",因为JavaScript停不下来,也就无法响应用户的行为。

你也许会问,JavaScript为什么是单线程,难道不能实现为多线程吗?

这跟历史有关系:

JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊。

JavaScript的单线程,与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。

比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?

所以,为了避免复杂性,从一诞生,JavaScript就是单线程,这已经成了这门语言的核心特征,将来也不会改变。

为了利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。

所以,这个新标准并没有改变JavaScript单线程的本质。

回到EventLoop:

单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。

如果排队是因为计算量大,CPU忙不过来,倒也算了,但是很多时候CPU是闲着的,因为IO设备(输入输出设备)很慢(比如Ajax操作从网络读取数据),不得不等着结果出来,再往下执行。

JavaScript语言的设计者意识到,这时主线程完全可以不管IO设备,挂起处于等待中的任务,先运行排在后面的任务。等到IO设备返回了结果,再回过头,把挂起的任务继续执行下去。

于是,所有任务可以分成两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous)。同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,

才能执行后一个任务;异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。

如下图:

Nodejs为什么选择javascript为载体语言

 只要主线程空了,就会去读取"任务队列",这就是JavaScript的运行机制。这个过程会不断重复。

三,实例讲解

好了,“废话”不多说了,马上开始我们第一个NodeJS应用:“Hello 大熊”。

打开你最喜欢的编辑器,创建一个HelloWorld.js文件。

代码如下:

1 var http = require("http") ;2 http.createServer(function(request,response){3 response.writeHead(200,{4 "Content-Type" : "text/plain"5 }) ;6 response.write("Hello,大熊 !") ;7 response.end() ;8 }).listen(8888) ;

我们来运行并且测试这段代码。首先,用Node.js执行你的脚本:

打开命令行工具CMD,切换到你的工作目录,运行命令“node HelloWorld.js”

接下来,打开浏览器访问http://localhost:8888/,你会看到一个写着 “Hello,大熊 !” 的网页。

一点小的扩展知识:

如下图所示,这是NodeJS中的http.js部分源码,createServer是一个对用户很友好的接口,内部实现采用了单例模式,这样做的好处是,把实例的创建和初始化任务进行有效的分离,职责专一,降低耦合度,这是大家平时编程时可以借鉴的思想。

Nodejs为什么选择javascript为载体语言

哈哈哈,是不是很有意思,这只是一次短暂的体验,后面会陆续讲解很多的知识点,大家慢慢体会O(∩_∩)O哈哈~

四,总体概述

1,它是一个Javascript运行环境

2,依赖于Chrome V8引擎进行代码解释

3,事件驱动

4, 非阻塞I/O

5, 轻量、可伸缩,适于实时数据交互应用

6,单进程,单线程

最后我想说的话是:这篇的例子不是很多,但是这些概念相当重要,一定要有一个清晰的理解,这样为以后的NodeJS学习会打下牢固的基础的,朋友们加油一起努力。

哈哈哈,本篇结束,未完待续,希望和大家多多交流够沟通,共同进步。。。。。。呼呼呼……(*^__^*)

NodeJs 相关文章推荐
跟我学Nodejs(二)--- Node.js事件模块
May 21 NodeJs
nodejs分页类代码分享
Jun 17 NodeJs
深入浅析NodeJs并发异步的回调处理
Dec 21 NodeJs
nodejs和php实现图片访问实时处理
Jan 05 NodeJs
简单实现nodejs上传功能
Jan 14 NodeJs
解决nodejs中使用http请求返回值为html时乱码的问题
Feb 18 NodeJs
nodejs实现邮件发送服务实例分享
Mar 29 NodeJs
nodejs6下使用koa2框架实例
May 18 NodeJs
NodeJS 中Stream 的基本使用
Jul 30 NodeJs
Nodejs调用Dll模块的方法
Sep 17 NodeJs
nodejs搭建本地服务器并访问文件操作示例
May 11 NodeJs
浅谈Node的内存泄露问题
May 06 NodeJs
NodeJS中Buffer模块详解
Jan 07 #NodeJs
Nodejs中读取中文文件编码问题、发送邮件和定时任务实例
Jan 01 #NodeJs
Nodejs中调用系统命令、Shell脚本和Python脚本的方法和实例
Jan 01 #NodeJs
nodejs中实现路由功能
Dec 29 #NodeJs
NodeJS制作爬虫全过程(续)
Dec 22 #NodeJs
NodeJS制作爬虫全过程
Dec 22 #NodeJs
nodejs中操作mysql数据库示例
Dec 20 #NodeJs
You might like
yii框架源码分析之创建controller代码
2011/06/28 PHP
php中使用explode查找某个字符是否存在的方法
2011/07/12 PHP
深入php 正则表达式的学习探讨
2013/06/06 PHP
php echo, print, print_r, sprintf, var_dump, var_expor的使用区别
2013/06/20 PHP
解析PHP中VC6 X86和VC9 X86的区别及 Non Thread Safe的意思
2013/06/28 PHP
Codeigniter的一些优秀特性总结
2015/01/21 PHP
PHP永久登录、记住我功能实现方法和安全做法
2015/04/27 PHP
PHP使用mysql与mysqli连接Mysql数据库用法示例
2016/07/07 PHP
模拟用户操作Input元素,不会触发相应事件
2007/05/11 Javascript
JavaScript 设计模式 安全沙箱模式
2010/09/24 Javascript
jquery 笔记 事件
2011/11/02 Javascript
javascript自定义startWith()和endWith()的两种方法
2013/11/11 Javascript
javascript带回调函数的异步脚本载入方法实例分析
2015/07/02 Javascript
javascript插件开发的一些感想和心得
2016/02/28 Javascript
举例说明JavaScript中的实例对象与原型对象
2016/03/11 Javascript
jQuery animate easing使用方法图文详解
2016/06/17 Javascript
js实现无缝循环滚动
2020/06/23 Javascript
vue的keep-alive用法技巧
2019/08/15 Javascript
JS window对象简单操作完整示例
2020/01/14 Javascript
原生jQuery实现只显示年份下拉框
2020/12/24 jQuery
Python实现约瑟夫环问题的方法
2016/05/03 Python
python3之微信文章爬虫实例讲解
2017/07/12 Python
python 上下文管理器使用方法小结
2017/10/10 Python
Python内置函数reversed()用法分析
2018/03/20 Python
python中的字符串内部换行方法
2018/07/19 Python
Linux下Python安装完成后使用pip命令的详细教程
2018/11/22 Python
python使用for循环计算0-100的整数的和方法
2019/02/01 Python
Python 获取windows桌面路径的5种方法小结
2019/07/15 Python
Python实现PyPDF2处理PDF文件的方法示例
2019/09/25 Python
python GUI库图形界面开发之PyQt5时间控件QTimer详细使用方法与实例
2020/02/26 Python
python实现批处理文件
2020/07/28 Python
如何完美的建立一个python项目
2020/10/09 Python
CSS3教程(7):CSS3嵌入字体
2009/04/02 HTML / CSS
几个解决兼容IE6\7\8不支持html5标签的几个方法
2013/01/07 HTML / CSS
html5页面结构_动力节点Java学院整理
2017/07/10 HTML / CSS
同学聚会致辞集锦
2015/07/28 职场文书