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 win7下安装方法
May 24 NodeJs
nodejs中exports与module.exports的区别详细介绍
Jan 14 NodeJs
NodeJs基本语法和类型
Feb 13 NodeJs
nodejs中实现阻塞实例
Mar 24 NodeJs
nodejs爬虫抓取数据之编码问题
Jul 03 NodeJs
Nodejs异步回调之异常处理实例分析
Jun 22 NodeJs
nodejs异步编程基础之回调函数用法分析
Dec 26 NodeJs
Nodejs异步流程框架async的方法
Jun 07 NodeJs
linux 下以二进制的方式安装 nodejs
Feb 12 NodeJs
nodejs使用socket5进行代理请求的实现
Feb 21 NodeJs
浅谈vue websocket nodeJS 进行实时通信踩到的坑
Sep 22 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
header与缓冲区之间的深层次分析
2016/07/30 PHP
Laravel多用户认证系统示例详解
2018/03/13 PHP
PHP Include文件实例讲解
2019/02/15 PHP
PHP设计模式之命令模式示例详解
2020/12/20 PHP
JQuery打造PHP的AJAX表单提交实例
2009/11/03 Javascript
ExtJs使用IFrame的实现代码
2010/03/24 Javascript
js图片自动切换效果处理代码
2013/05/07 Javascript
从JQuery源码分析JavaScript函数的apply方法与call方法
2014/09/25 Javascript
JavaScript代码应该放在HTML代码哪个位置比较好?
2014/10/16 Javascript
JavaScript返回0-1之间随机数的方法
2015/04/06 Javascript
详解nodeJS之路径PATH模块
2017/05/31 NodeJs
jQuery查找和过滤_动力节点节点Java学院整理
2017/07/04 jQuery
Cropper.js 实现裁剪图片并上传(PC端)
2017/08/20 Javascript
vue组件生命周期详解
2017/11/07 Javascript
基于datepicker定义自己的angular时间组件的示例
2018/03/14 Javascript
基于JavaScript实现幸运抽奖页面
2020/07/05 Javascript
JS+CSS3实现的简易钟表效果示例
2019/04/13 Javascript
react koa rematch 如何打造一套服务端渲染架子
2019/06/26 Javascript
浅谈vue中document.getElementById()拿到的是原值的问题
2020/07/26 Javascript
解决VUE mounted 钩子函数执行时 img 未加载导致页面布局的问题
2020/07/27 Javascript
[03:16]DOTA2完美大师赛主赛事首日集锦
2017/11/23 DOTA
python 生成目录树及显示文件大小的代码
2009/07/23 Python
Python 分析Nginx访问日志并保存到MySQL数据库实例
2014/03/13 Python
深度剖析使用python抓取网页正文的源码
2014/06/11 Python
python中查看变量内存地址的方法
2015/05/05 Python
Python实现mysql数据库更新表数据接口的功能
2017/11/19 Python
利用Python实现在同一网络中的本地文件共享方法
2018/06/04 Python
基于DATAFRAME中元素的读取与修改方法
2018/06/08 Python
解决Python3.8用pip安装turtle-0.0.2出现错误问题
2020/02/11 Python
AmazeUI 折叠面板的实现代码
2020/08/17 HTML / CSS
德国汽车零件和汽车配件网上商店:kfzteile24
2018/11/14 全球购物
美国温暖商店:The Warming Store
2018/12/15 全球购物
领导班子四风对照检查材料思想汇报
2014/09/26 职场文书
护士心得体会范文
2016/01/25 职场文书
nginx处理http请求实现过程解析
2021/03/31 Servers
springboot用户数据修改的详细实现
2022/04/06 Java/Android