Node.js 自学之旅(初稿篇)

学习基础,JQuery 原生JS有一定基础,有自己一定技术认知(ps:原型链依然迷糊中.闭包6不起来!哎!)

当然最好有语言基础,C#,java,PHP等等..

最初学习这个东西的原因很简单,在园子里面看到一篇关于node编写的小爬虫 的文章,没想到这个可以做一些服务自己的东西而不是公司那些服务用户啊什么什么的.总之不牵扯到公司的技术都很感兴趣,后来发现angluar.js里面也有node.js一点身影,好吧,好吧逼我呗..so 学吧!说实话并不想靠掌握这个如果升职加薪如何如何的,我只想做自己喜欢的事儿写服从于我自己的程序,就是这么简单.

这里要说明一下文中很多地方都是各出引用过来,对于很多不明白的地方会针对某个对象,方法等作出补充说明,争取学习不留死角,一般一片学习很少很少的内容却需要大量的补充来填补知识空白这也许就是最难的地方.

Day 01 

言归正传,node.js简介:

简单的说 Node.js 就是运行在服务端的 JavaScript。

Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。

Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。

模块化(module),JS的致命伤一直计划引进据说ES6中已经引入了模块化概念了并没有实际实现(知识薄浅,书到用时方恨少),通过实现CommonJS中的Modules1.0概念来完善自己的模块化

   2017-01-03 更新

   补充一下:关于nodejs里面的模块化知识点(module),nodejs模块化大致分为两类一类是原生模块(跟JS一样原生什么的都是重中之重),另外一类是文件模块

   文件模块

文件模块,我首先想到的是类似与C#里面文件数据交互相关的IO数据流,其实不然nodejs中文件模块引用了三种文件识别方式:

  1. .js  既然是模块化 当然自己得有个专门处理文件的模块了 -- fs模块(那笔记下来好不容易找到的--)

       FS模块刚刚被我言中了,采用的是标准的POSIX文件 I/O操作集(不明白的童鞋自己去百度吧,不能再深入了!),可以通过nodejs中的require("fs")来唤起该模块并且该模块有同步/异步两种传输方式:

         1)两种方式不同点在于 同步传递文件时候会出现程序异常,当然可以trycatch捕获到,而异步传递时候会直接返回null或者undefined

         2)读取文件时一定要设置文件编码,默认编码是'buffer'如果你在下面的例子中文件里面输入的是中文就能明显的看出来了!

         下面介绍两个例子,这是下面具体实例:

//文件读取操作
 var fs = require("fs") ;
 fs.readFile("bb.txt","utf8",function (error,data){
     if(error) throw error ;
     console.log(data) ;
 }) ;

//文件写入操作
var fs = require("fs") ;
 var txt = "大家要好好学习NodeJS啊!!!" ;
 //写入文件
 fs.writeFile("bb.txt",txt,function (err) {
     if (err) throw err ;
     console.log("File Saved !"); //文件被保存
 }) ;

  2.".node"  Addon这个是C/C++编写的操作原理未知...通过其中的dlopen方法来进行加载(想更深入的童鞋请自行百度)

     3.".Json" 这个大家都不会陌生 尤其做前端的小伙伴们 这个是调取JSON.parse 方式来解析json数据的

   原生模块

   关于原生模块,也就是nodejs自带模块还是参考一下官方文档吧,毕竟那个东西是最最基础的最最可信的.

   NodeJS模块查询策略

   node提供了两个对象,exports和require两个对象,其中exports是模块公开的接口,require是从外部获取一个模块接口,即所获取模块的exports对象.(这句话有点难以理解稍后有解释)

   原生模块在nodejs编译进了二进制执行文件,加载速度最快,另外就是文件模块速度肯定比不上原生模块,但是由于加载机制,已经加载过的原生模块和文件模块不会再次被重新加载,如图:

   这就很明朗了,这么吊的图肯定不是我画的呀 大神传送门-->https://liuzhichao.com/p/1669.html

    刚才提到有两个对象exports和require,这个图很详细说明了这哥俩之间的关系,我是这样理解的:

       require对象就像JQuery中的$选择器,这个大家肯定不陌生,当然有区别的,只是个比喻 如果把页面元素都划分为模块的话$("<div></div>"),很简单吧.我选择的就是div这个模块,好比require("fs")选择的是原生模块fs,有一点不知大家感觉到没有,nodejs缓存机制特别到位,优先缓存查找有点像radis缓存一样一些已经执行过方法不会被再次执行大大缩减了重复调取的性能损耗,但是这里不得不提及缓存问题,机制固然好毕竟这东西是一把双刃剑性能上去了,缓存溢出咋办?有没有专业的缓存清理机制,目前还不几道,不过我肯定他绝对有.

     其次require接收的参数是啥? 1.原生模块 2.相对,绝对路径文件模块 3.非原生模块的文件模块. require的查找线路是当年文件目录的node_modules开始找,找不到就找父级目录node_module以此类推直到根目录下的node_module文件为止,第二条的时候大家肯定注意到绝对路径!  没错性能就在一瞬间了 如果你给文件模块地址是绝对地址,必然相当快省去反复遍历时间而且require的查找机制不是遍历全局这种机制  so好好利用这一点:

    

  1. 从module path数组中取出第一个目录作为查找基准。
  2. 直接从目录中查找该文件,如果存在,则结束查找。如果不存在,则进行下一条查找。
  3. 尝试添加.js、.json、.node后缀后查找,如果存在文件,则结束查找。如果不存在,则进行下一条。
  4. 尝试将require的参数作为一个包来进行查找,读取目录下的package.json文件,取得main参数指定的文件。
  5. 尝试查找该文件,如果存在,则结束查找。如果不存在,则进行第3条查找。
  6. 如果继续失败,则取出module path数组中的下一个目录作为基准查找,循环第1至5个步骤。
  7. 如果继续失败,循环第1至6个步骤,直到module path中的最后一个值。
  8. 如果仍然失败,则抛出异常。

      这里的异常是有区别的下文提及调用类型有同步异步两种 同步调用肯定就是异常了,这个可以trycatch截取到 另外就是异步调用啦 返回null或者undefined..很简单的说 

  Exports  or  module.exports

    首先必须理解了上面哪个图,自然而然就会产生一个疑问exports干毛用的?为毛都返回的是exports,难道就是简单的对象返回问题?

    带着问题,这里有三个例子:创建两个文件,server.js和test.js

    server.js中代码

    

var add=function(a,b){
    return a+b;
};

var minus=function(a,b){
	return a-b;
};

  test.js中的代码

 

var test=require("./server");
console.log(test.add(4,2));

  然后执行test.js文件 神奇的效果出现了!!      异常报错!

     修改一下server.js代码

var add=function(a,b){
    return a+b;
};

var minus=function(a,b){
	return a-b;
};

exports.add=add;
exports.minus=minus;

  结果为 6!  简单说明一下子 首先是require选择执行文件server.js 结合上面哪个图,之后nodejs 就去找了..哎~找到了 但是返回的是啥 他本身不认识 而是通过对象返回才认识的! 这个传递的快递小哥就是exports!很明朗了吧!

呐是不是就可以认为返回的东西都可以往exports里面放呢?真的只是他自己返回的嘛?别忘了之前为啥叫module模块化!当然module.exports,这里我就懒一下子 不举例给大家啦 当然原文地址不能少:https://liuzhichao.com/p/1669.html

    关于exports和module.exports 我个人是这样理解的,因为node中没有类的概念而某些特定情况下需要返回一个特定"对象"这种情景下module.exports就排上用场了 指定的对象情况,而exports并非指定的对象,也就是位置对象类型,这个有点类似C#中的泛型和非泛型...只是说类似,纯属个人理解.

2017-01-06 补完结

 如题谷歌V8引擎,听起来吊吊的 实际上也是很吊的,前端开发的同学对于谷歌浏览器并不陌生或多或少接触过或者使用过我就不多介绍啦,主要是多了我也不知道哈哈.但是最显而易见的效果在于node处理高并发问题上有突出效果!

安装环境 windows啊,linux啊,os啊,自己去看 网址在这里:https://nodejs.org/en/download/

安装过程就不多说了,哦,有一点对于DOS命令不熟的童鞋们还是老老实实安装C盘吧 ,或多或少会用到一点点 .教程:http://jingyan.baidu.com/article/656db9189b826ce381249ce8.html

搞完了之后看看系统PATH环境里面有没有配置node.js:

检测PATH环境变量是否配置了Node.js,点击开始=》运行=》输入"cmd" => 输入命令"path",输出如下结果:

PATH=C:\oraclexe\app\oracle\product\10.2.0\server\bin;C:\Windows\system32; C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\; c:\python32\python;C:\MinGW\bin;C:\Program Files\GTK2-Runtime\lib; C:\Program Files\MySQL\MySQL Server 5.5\bin;C:\Program Files\nodejs\; C:\Users\rg\AppData\Roaming\npm

似乎就是你所安装的node.js的地址不过这东西没有的话node是运行不起来的!找到它 没有的话就添加上!

当然可以手动修改一下Path地址右键我的电脑-属性-高级系统设置-环境变量-找到path 关于nodejs那段文字 修改去吧~只要吧你的文件地址搞上面去就行了,别的别轻易动,虽然我也不知道会发生什么但是我还是鼓励喜欢动手的小伙伴修改一下试试看!

搞完了之后基本工作就完成了!当然安装的不仅仅是node.js安装同时也会默认安装台的包管理工具npm! 个人认为比较强大的包管理工具,有点像git工具一样可以直接用命令从服务器更新啊,下模块啊,上传自己的包啊等等,反正很好用可以搞很多事儿理解有限以后我再详细研究一下子
输入npm-v直接显示当前npm的版本,今儿先到这吧 该吃饭了!

Day02

继续昨天的学习,(拍桌!,上课了啊,写博客的时候肯定是欧美音乐最配(Outside--Calvin Harris)).关于npm命令其实不算很多很多,起码比dos命令少不少呢废话少说npm命令大全and各个命令用处持续更新中..来自园子内另外一位大神~:http://www.cnblogs.com/PeunZhang/p/5553574.html

简单说一下需要用到的命令,npm install <Module name>  添加模块,一看就知道 npm install 模块名称 没难度无压力.还有一点需要注意一下啊,当你install的时候 默认是node安装目录的,也就是你的本地目录local,既然有本地目录当然就会有全局目录了!没错 npm install <Module name>-g 就是安装在全局环境中,这两种有啥区别呢?我尝试了一下本地安装local需要npm到指定目录之后运行指定的模块,儿全局不用,随便用随时随地,当然这些不是空想,是根据配置文件设定滴找到npm

安装根目录有个package.json里面有所有模块的安装信息,版本啊.你问npm的问题基本npm都是在这找的,虽然很多模块我还木有用过不过感觉找到了NPM的老窝了!很多很吊的功能官方文档比谁说的都清楚:https://docs.npmjs.com/

哦对了,除了nodejs自带的npm管理器(据说国内比较慢...没赶脚)还有国内用的比较多淘宝NPM镜像可以直接用npm install一个功能和npm及其相似也有不同的地方很少:

$ npm install -g cnpm --registry=https://registry.npm.taobao.org


官方文档:http://npm.taobao.org/。搞完了之后就可以用cnpm install愉快的安装模块啦

工具方面的已经介绍的差不多啦,言归正传,贵言转正 可以真正开始nodejs的学习之旅楼

    第一个"应用"(Prayer In C(Lilly Wood and The Prick))

如果我们使用PHP来编写后端的代码时,需要Apache 或者 Nginx 的HTTP 服务器,并配上 mod_php5 模块和php-cgi。

从这个角度看,整个"接收 HTTP 请求并提供 Web 页面"的需求根本不需 要 PHP 来处理。

不过对 Node.js 来说,概念完全不一样了。使用 Node.js 时,我们不仅仅 在实现一个应用,同时还实现了整个 HTTP 服务器。事实上,我们的 Web 应用以及对应的 Web 服务器基本上是一样的。(这么有深度的话肯定不是我写的..)

   1.先唤醒nodejs,让他知道咱们在召唤他--->required 初始化自毁程序

   2.已经有了足够强大的力量必须要建立自己的帝国巩固势力啦,创建服务器,他的职责在于监管部门,监听服务端的各种请求.类似Apache,Nginx等http服务器(表示听都没听过!)

   3.既然有监管的功能当然不能光吃饭不干活,接收请求,响应请求,客户端发送http请求,服务端响应请求,还有啥..没别的了

既然三要素已经有了,还等什么建立以下自己的帝国吧:

搞一个server.js文件 在npm根目录里面

//召唤神龙,唤起nodejs
var DG=require("http");
//创建帝国,建立服务器,我学过一点C#记忆中 http请求中似乎有两个参数request和response试试看呗
DG.createServer(function(request,response){
//搞事
//搞个头部信息粗来简单点的
    response.writeHead(200, { 'Content-Type': 'text/plain' });

    response.end('HelloWorld\n');
    }).listen(8888);

console.log("Server run at 127.0.0.1:8888");

  麻溜试试去吧,我试了一下  直接 node server.js  好的神龙粗线了, 访问127.0.0.1:8888  ok浏览器粗线了!!

看起来苏护很难搞的样子,其实也不是很难.原理大概是这个意思唤起nodejs使用require

 

 Day03 元旦假期回来第一波 (NPM包管理工具自我感觉不是很详细,以后继续补充)

 Nodejs--REPL 交互式解析器

     听起来很高大上有木有,干嘛用的?很简单来一起看看定义-->看大屏幕-->REPL Read Eval Print Loop交互式解析器,类似某些运行环境  windows..linux..unix等等,我们可以输入命令然后环境进行解析之后给我们答案!就像计算器一样你按1+1然后按= 屏幕显示2,这就是交互解析器!很好理解吧.

     在node上运行一下试试呗,我这是windows环境 直接点击node.exe 输入1+1 回车直接出结果了..soeasy 来点简单逻辑怎么样来来看图:

    REPL解析器都干了些什么事儿呢?

      >1.读取 读取用户输入 解析用户输入的javascript代码

      >2.执行 执行输入的数据结构

      >3.打印 打印执行结果

      >4.循环 循环操作以上步骤 直到用户ctrl+c主动退出

  作用:  啰嗦半天只想说明一点,REPL可以用作模块测试,它可以很好的被其他模块包容在内可以自己独立执行,可以作为 debugging testing或者只是执行一些操作得到一些结果.

ctrl + c - 终止当前命令

ctrl + c twice - 终止Node REPL

ctrl + d - 终止Node REPL

Up/Down Keys - 查看命令历史记录和修改以前的命令

tab Keys - 当前指令的列表

help - 所有命令的列表

break - 退出多行表达式

clear - 从多行表达退出

save filename - 当前Node REPL会话保存到文件中

load filename - 加载文件的内容在当前Node REPL会话

解析器这没啥可以说的 主要是做测试用 ...三个点是系统自动生成表示程序某些语句未完结,nodejs会自动识别当前语句是否完结,_下划线可以代表其中的变量 作为变量去接收各种参数,但是不推荐这么搞 很不规范的说

 

 

Day04 回调函数(对于有一定JS经验的人来说非常非常容易理解)

   其实想写一些关于回调函数的帖子的!但是..此处省略一万字, 我发现一些更加实用更应该注意到的事情,都知道nodejs是运行在服务端的js但是后端很多的encod啊decod操作是如何实现的关于编码格式如何实现的?

那么就根据这个回调函数一并说一下呗,还有我发现我这种单一帖子续写很让人反感,好吧我错了大大们,明天开始从day05开始我会划分成类这样更加清晰展现每一个模块深挖之后的原理!

  如图,关于回调神马的我真的不想说太多,把这个梨子上的代码老老实实敲打一遍,然后自己运行之后比对一下子!,原理很简单 我自己总结就是异步处理与同步处理的区别,这也是处理并发的关键点之一,我可以同时请求A B两个任务而且不需要他们做出回应我就可以继续去做别的事儿等他们有反应了再来告诉我我再去处理,而同步就不一样了一就是一二就是二舅,这件事儿没完事儿别的啥都别想,两个方式各有各的优势,作用肯定不一样.好了再来看这个:

 

 如果你在刚才的input.txt里面输入过中文,控制台肯定显示的是空呗 这是为毛线?nodejs对中文支持并不好!记住了并不好!所以需要第三方库的支持,如果你简单的相信data.toString()可以实现愿望的话那么久错啦,因为这不同于其他后端代码对于这种多字节的node并不支持,而且toString([encoding],[strat],[end])虽然可以选择编码格式但是却不支持gbk gb2312 等等多字节编码.so我们要引用第三方库来实现它强大的中文怎么可能不被支持呢?

  iconv-lite 就是这个库

 

 

posted @ 2016-12-29 18:11  流年过往  阅读(345)  评论(0编辑  收藏  举报