node.js新手入门初学

新公司后端需要用到node.js做开发,由于本人在此之前实习亦或是在学校做的项目仅仅使用java所谓后端语言进行项目的开发,所以在入职之前先是自己学习node.js基础的知识,方便进公司后能快速上手工作内容。以下是本人在学习时候做的笔记内容,仅仅是基础知识的概括,并未深入研究以及使用。

  • Node.js 是什么
    • JavaScript 运行时
    • 既不是语言,也不是框架,它是一个平台
  • Node.js 中的 JavaScript
    • 没有 BOM、DOM
    • EcmaScript 基本的 JavaScript 语言部分
    • 在 Node 中为 JavaScript 提供了一些服务器级别的 API
      • 文件操作的能力
      • http 服务的能力

Node.js特性
  • 单线程:在Java、PHP或者.net等服务器端语言中,会为每一个客户端连接创建一个新的线程,而每个线程需要耗费大约2MB内存,理论上一个8GB内存的服务器可以同时连接的最大用户数为4000个左右。要让Web应用程序支持更多的用户,就需要增加服务器的数量,而Web应用程序的硬件成本当然就上升了。Node.js不为每个客户连接创建一个新的线程,而仅仅使用一个线程。当有用户连接了,就触发一个内部事件,通过非阻塞I/O、事件驱动机制,让Node.js程序宏观上也是并行的。使用Node.js,一个8GB内存的服务器,可以同时处理超过4万用户的连接。另外,单线程的带来的好处,还有操作系统完全不再有线程创建、销毁的时间开销。

  • 非阻塞I/O:因为CPU的效率是远远高于I/O设备的执行效率的,如果让CPU去等待I/O的执行,将会极大地浪费时间,降低性能,比如在访问数据库或者读文件的时候,在传统的单线程处理机制中,在执行了访问数据库或文件代码之后,整个线程都将暂停下来(阻塞I/O),等待数据库或者文件系统返回结果才能执行后面的代码。I/O阻塞了代码的执行极大地降低了程序的执行效率。由于Node.js中采用了非阻塞型I/O机制,因此在执行了访问数据库或文件的代码之后,将立即转而执行其他代码,把返回结果的处理代码放在回调函数中,从而提高了程序的执行效率。当某个I/O执行完毕时,将以事件的形式通知执行I/O操作的线程,线程执行这个事件的回调函数。为了处理异步I/O,线程必须有事件循环,不断的检查有没有未处理的事件,依次予以处理。阻塞模式下,一个线程只能处理一项任务,要想提高吞吐量必须通过多线程。而非阻塞模式下,一个线程永远在执行计算操作,这个线程的CPU核心利用率永远是100%。所以,这是一种特别有哲理的解决方案:与其人多,但是好多人闲着;还不如一个人玩命,往死里干活儿。

  • 事件驱动:在Node中,客户端请求建立连接,提交数据等行为,会触发相应的事件。在Node中,在一个时刻,只能执行一个事件回调函数,但是在执行一个事件回调函数的中途,可以转而处理其他事件,然后返回继续执行原事件的回调函数,这种处理机制,称为“事件环”机制。Node.js底层是C++(V8也是C++写的),底层代码中,近半数都用于事件队列、回调函数队列的构建。

  • 优缺点:因为单线程,在处理大规模并发的任务中还是会显得力不从心的,比如在CPU密集型事务中就会遇到瓶颈,另外就是node.js是没有web容器的,代码直接没有根目录的说法,在一定程度上为程序员增加了代码量,但也提高了灵活性,为高级路由带来了极大的方便,在node.js中回调函数会有很深的层次,为代码的阅读多多少少造成了一定的障碍。善于处理异步事件(callback),处理同步事务中需要额外的负担。

  • 适用范围:当应用程序需要处理大量并发的I/O,而在向客户端发出响应之前,应用程序内部并不需要进行非常复杂的处理的时候,Node.js非常适合。Node.js也非常适合与web socket配合,开发长连接的实时交互应用程序。比如:用户表单收集、考试系统、聊天室、图文直播、提供JSON的API(为前台Angular使用)


  • 模块系统
    • 在 Node 中没有全局作用域的概念
    • 在 Node 中,只能通过 require 方法来加载执行多个 JavaScript 脚本文件
    • require 加载只能是执行其中的代码,文件与文件之间由于是模块作用域,所以不会有污染的问题
      • 模块完全是封闭的
      • 外部无法访问内部
      • 内部也无法访问外部

  • 核心模块
    • 核心模块是由 Node 提供的一个个的具名的模块,它们都有自己特殊的名称标识,例如
      • fs 文件操作模块 (filesystem)
      • http 网络服务构建模块
      • os 操作系统信息模块
      • path 路径处理模块
      • 。。。。
    • 所有核心模块在使用的时候都必须手动的先使用 require 方法来加载,然后才可以使用,例如:
  • 简单引用Http模块示例启动服务器
//require表示引模块,引模块就是引用自己的一个特殊功能
var http = require("http");
//创建服务器,参数是一个回调函数,表示如果有请求进来,要做什么
var server = http.createServer(function(req,res){
     
    //req表示请求,request;  res表示响应,response
    //设置HTTP头部,状态码是200,文件类型是html,字符集是utf8
    res.writeHead(200,{
     "Content-type":"text/html;charset=UTF-8"});
    res.end("hello,world!");
});

//运行服务器,监听3000端口(端口号可以任改)
server.listen(3000,function(){
     
	console.log('服务器启动成功!!!,请访问http://127.0.0.1:3000/ 来访问')
})

注意:在node.js中必须使用res.end()函数来返回,不然的话浏览器会认为服务器还没有结束本次的数据传输,而一直进入忙等状态,这点值得警醒。


  • 模块间的通信
    • require 方法有两个作用:
    1. 加载文件模块并执行里面的代码
    2. 拿到被加载文件模块导出的接口对象
  • 在每个文件模块中都提供了一个对象:exports

    exports 默认是一个空对象

    你要做的就是把所有需要被外部访问的成员挂载到这个 exports 对象中
  • b.js:
exports.foo = 'hello'
  • a.js (要访问到b.js的变量foo)
var bExports = require('./b')

console.log(beExprots.foo)

你可能感兴趣的:(node.js笔记,node,js,node.js)