NodeJs简明教程(1)

NodeJs简明教程将从零开始学习NodeJs相关知识,助力JS开发者构建全栈开发技术栈!前端

本文是NodeJs简明教程的第一篇,将介绍NodeJs总体架构以及重点概念。node

NodeJs到底是什么

来看一段官方的说法[1]:浏览器

As an asynchronous event driven JavaScript runtime, Node is designed to build scalable network applications. In the following "hello world" example, many connections can be handled concurrently. Upon each connection the callback is fired, but if there is no work to be done, Node will sleep.服务器

Google翻译版本:网络

做为异步事件驱动的JavaScript运行时,Node旨在构建可伸缩的网络应用程序。 在下面的“hello world”示例中,能够同时处理许多链接。 在每次链接时都会触发回调,可是若是没有工做要作,Node将会休眠。多线程

结合上面的介绍,咱们能够得出一个结论:架构

NodeJs的本质是一个Javascript运行时。该运行时基于异步事件驱动进行运做。app

异步

本文中的异步指异步IO。维基百科对异步IO的定义[2]:异步

异步IO是计算机操做系统对输入输出的一种处理方式:发起IO请求的线程不等IO操做完成,就继续执行随后的代码,IO结果用其余方式通知发起IO请求的程序。与异步IO相对的是更为常见的“同步(阻塞)IO”:发起IO请求的线程不从正在调用的IO操做函数返回(即被阻塞),直至IO操做完成。async

一言以蔽之就是:

执行IO请求后,调用方不等执行结果就继续执行下面的代码,IO操做完成后执行者会告诉调用者“我执行完了”。在NodeJs中通知方式是“回调”。

事件驱动

事件驱动是相对 线程驱动 而言的。线程驱动 下服务器为每一个请求新建一个线程去处理。 维基百科对事件驱动的定义[3]:

事件驱动程序模型下的系统,基本上的架构是预先设计一个事件循环所造成的程序,这个事件循环程序不断地检查当前要处理的信息,根据要处理的信息运行一个触发函数进行必要的处理。其中这个外部信息可能来自一个目录夹中的文件,可能来自键盘或鼠标的动做,或者是一个时间事件。

以NodeJs的HTTP服务器为例,当调用server.listen函数时,NodeJs就会建立一个事件循环,当有客户端请求过来时,NodeJs将该请求入队列进行后续处理,主线程以及轮询客户端请求并入队列,队列中的请求执行完毕后会经过回调函数的形式通知主线程,如此循环。

Javascript运行时

Javascript运行时是个比较复杂的概念,本文在介绍 Javascript运行时 以前介绍一下 Javascript引擎

Javascript引擎

维基百科的定义[4]:

JavaScript引擎是一个专门处理JavaScript脚本的虚拟机,通常会附带在网页浏览器之中。

我的理解:

Javascript引擎主要是对Javascript代码进行词法、语法等分析,经过编译器将代码编译成可执行的机器码让计算机去执行。

目前业内出名的Javascript引擎非V8莫属了。

运行时的组成

Javascript能够运行在浏览器,也能够运行在服务器(NodeJs)中,有些API或者对象只有浏览器有(好比DOM,BOM等),而有些API或者对象只有服务器中有(如文件操做,HTTP服务器等)。

Javascript运行时包括了Javascript引擎、特定环境API、事件循环和事件队列。

NodeJs架构图

NodeJs由C++语言基于libuv开发,分层设计,Javascript只是其基于V8提供的上层接口,换句话说,若是把上层接口换成其余语言实现,好比换成PHP实现,那么PHP就能够实现异步事件驱动的服务器,运行时名称就成为 NODE-PHP

NodeJs架构图

  • Node standard library NodeJs标准库,也是直接提供给开发者调用的顶层代码
  • Node bindings Javascript和libuv在该层进行通讯,基于V8打通语言壁垒
  • V8 执行JS代码
  • libuv 高性能异步I/O、事件驱动、线程池的库,也是NodeJs高性能的保证
  • C-ares 提供异步DNS
  • http_parser、OpenSSL、Zlib 提供HTTP解析、openssl加解密、数据压缩等接口

NodeJs究竟是不是单线程

不是,主线程Javascript线程是单线程,libuv提供线程池,NodeJs不单单是一个Javascript引擎,而是一套运行时,不能将Javascript线程孤立出来。

NodeJs为何这么快

  1. 单线程解决了多线程环境下线程切换开销以及可能的线程同步开销
  2. 异步+事件驱动保证了NodeJs主线程不会阻塞,会一直接受请求(这也是受人诟病的地方,其余语言实现的服务器,请求过大会排队处理,NodeJs会将请求所有入队,致使内存暴涨)

NodeJs优缺点以及适合的场景

  1. 因为主线程Javascript线程是单线程,因此主线程不能作CPU密集操做(好比什么加解密之类的,这种操做只能有Javascript线程运行,会阻塞事件循环),因此NodeJs适合I/O密集场景,好比常见的(TCP/HTTP服务器)
  2. 对于前端开发者来讲,几乎没有语言门槛
  3. 跨平台,NodeJs在主流操做系统都有对应的二进制程序
  4. 标准库强大,第三方库也不少,下降了造轮子成本
  5. 易于部署,服务器安装一个NodeJs程序配合NPM包管理器便可运行,不用像PHP那样还要安装扩展,配置前端HTTP服务器

结语

欢迎继续关注本系列文章。

参考文献

  1. About NodeJs
  2. 异步IO
  3. 事件驱动
  4. Javascript引擎
相关文章
相关标签/搜索