1,node的文件系统
问题1:执行module_test,可以正常打印写的内容,但是watcher.js无打印
—— 1.1 弄错文件的层级,所以一直找不到文件,module
—— 1.2 创建target.txt的位置不对,造成代码找不到模块
问题2,修改target.txt 文件,保存一次,但是控制台有两次文件修改的打印,为什么?
2,books
1,《node.js实战 第2版》—— 中国工信出版社
主要是前端构建系统,流行的node web框架,express搭建web程序,node做命令行开发者工具,electron桌面程序。
1.1 ) node基础编程
1.2)node web程序(node做服务器),node服务器框架
1.3)node和数据库
1.4)node写命令行工具和electron桌面程序
2,《node.js 开发实战》 —— 华中科技大学出版社
2.1,node基础编程(node事件循环,node文件处理,node的I/O开发)
2.2,node的数据处理
2.3,node开发web应用
3,笔记 —— 《node.js实战》
如何学习一门新的语言
1,先看这个语言有什么特性,
2,这个语言可以做什么 —— 做web,数据处理,桌面应用(Express写框架很简单,有一个todolist的项目,但是基础的知识还是要看)
1,书的结构
1.1)node.js 基础技术
1.2)node写web程序node创建web程序,node储存数据web的相关中间件框架Express框架用模板把数据展示从逻辑中抽出来 —— 但是最新的web不再使用模板
1.3)node部署到生产环境
2,读书笔记
第一部分:node基础
第一章 node基础
1,浏览器中的js异步
2,服务器中的异步在其他的后台语言,如php中,是I/O阻塞的,如果程序在一个I/O上阻塞,更多的请求过来的时候,一般会使用多线程,给每一个连接分配一个线程,并且为这些连接设置一个线程池。线程通常处于进程(一个程序一个进程)之内,对于一个进程,可能有多个请求的线程,
3,DIRT程序因为Node自身在I/O上非常轻量,它善于将数据从一个管道混排 或代理到另一个管道上,这能在处理大量请求时持有很多开放的连接,并且只占用一小部分内存。 它的设计目标是保证响应能力,跟浏览器一样。——(还不理解)
4,node可以做http服务器
5,node处理流数据
5.1)什么是数据流:数据可以被分为一块一块的传送,每收到一块数据就开始处理,而不用等所有数据到全了再处理。代码执行:只要新的数据块准备好,就会激发data事件,当所有的数据加载完成就会激发end事件,程序可以边读取边处理(比数据都缓存到内存中在处理效率高很多)
5.2)什么是管道:可读,可写数据流结合起来就是管道
第二章 node原生实时程序
1,实时的程序需要的协议不仅是http,而是UDP协议,所以node需要支持http和websocket
2,常用的一些数据会缓存到内存中,访问内存(RAM)要比访问文件系统快得多,所以Node程序通常会把常用的数据缓存到内 存里。我们的聊天程序就要把静态文件缓存到内存中,只有第一次访问的时候才会从文件系统中 读取。下一个辅助函数会确定文件是否缓存了,如果是,就返回它。如果文件还没被缓存,它会从硬盘中读取并返回它。如果文件不存在,则返回一个HTTP 404错误作为响应。(一个程序的初始网络连接:浏览器的第一个进入项目的请求如何处理)第一拿到请求的服务器处理
3,http服务器运行成功问题:没有办法一步一步的执行代码,不知道服务器如何断点
4,把socket也绑定在这个http服务器,这样socket就可以和http共享一个端口
第三章
1,主要内容:
1.1)如何组织代码
1.2)如何异步
2,书中摘要知识点
2.1 node使用模块组织代码 —— exports 和 require
2.1.1)如何构建模块
2.1.1.1)exports 和 require文件目录下的index.js文件,包含 exports 属性 ,使用的是require属性
- require 是js中少数的同步I/O操作
- require引入文件的扩展名 .js 可以省略
- exports在js中不能重写
- module.export 和 export的作用
程序最终在模块中导出的是module.exports ,exports 只是对module.exports的全局引用,所以exports.myFun 只是 module.exports.myFun的简写,所以如果在同一个模块,使用了module.exports和 expotrs ,程序最终会执行 module.exports,再把exports设定为别的,就打破了module.exports 和 expotrs之前的引用关系,那exports就没有用了,因为它不再指向module.exports 。如果在一个模块中同时使用 module.exports 和 expotrs,就要写成module.exports = expotrs = Currency2.1.1.2)node_modules 模块require的模块要有相对的位置,但是在node_modules中的模块不用写相对位置(特殊的模块机制)2.1.2)模块放在哪儿 —— 只要指定了相对路径就行2.1.3)创建模块和使用模块做了什么 - node_modeules的依赖模块查找流程
P 41(书上) - node中有路径的模块的查找流程
P 42(书上) - 在node中,如果引入了一个模块,node会把这个模块作为对象缓存到内存中,下次使用的时候,直接从内存中读取
2.2 异步编程node的异步有两种,回调和事件监听
2.2.1)回调(用回调处理一次性事件)
- 不断在回调中使用回调,就会造成回调地狱(自己写的时候能看懂,但是别人看不懂,所以把回调函数单独封装一层,减少地狱)
- er 和 err 都表示错误
2.2.2)事件发射器(用事件发射器处理重复性事件)node的api,把http服务,TCP服务都处理成事件发射器(事件监听器,比如http服务,启动服务,浏览器打开就是用事件获取到服务的信息,所以就是事件出现触发的回调函数)
- http服务 http.createServer
- TCP服务socket.on
注:创建的事件发射器,不是很了解,后续关注
2.2.3)异步的流程控制
1)流程有:串行,并行
2)如何做串行流程控制为了用串行化流程控制让几个异步任务按顺序执行,需要先把这些任务按预期的执行顺序放 到一个数组中。这个数组将起到队列的作用:完成一个任务后按顺序从数组中取 出下一个。 数组中的每个任务都是一个函数。任务完成后应该调用一个处理器函数,告诉它错误状态和结果。如果有错误,处理器函数会终止执行;如果没有错误,处理器就从队列中取出下一个任务 执行它。
3)如何做并行流程控制为了让异步任务并行执行,仍然是要把任务放到数组中,但任务的存放顺序无关紧要。每个 任务都应该调用处理器函数增加已完成任务的计数值。当所有任务都完成后,处理器函数应该执 行后续的逻辑。
4,笔记 —— 《深入浅出node.js》
一,模块:
1,模块
1.1 模块的实现
1.2 node模块的引入流程
1.3 包与npm
书中摘要
1)可以看出,当前文件的路径越深,模块 查找耗时会越多,这是自定义模块的加载速度是最慢的原因
2)Node会按.js、.json、.node的次序补 足扩展名,依次尝试。
3)在Node中,每个文件模块都是一个对象
4)为了符合CommonJS模块规范,从JavaScript 到C/C++的过程是相当复杂的,它要经历C/C++层面的内建模块定义、(JavaScript)核心模块的定义和引入以及(JavaScript)文件模块层面的引入。但是对于用户而言,require()十分简洁、 友好。
5)为了同时能够享受到NPM上众多的包,同时对自己的包进行保密和限制,现有的解决方案就 是企业搭建自己的NPM仓库。
6)前后端JavaScript分别搁置在HTTP的两端,前者的瓶颈在于带宽,后者的瓶颈则在于CPU和内存等资源。
2,异步 I/O
2.1,为什么要异步并发,并行
2.2 异步I/O实现的现状
2.3 node的异步I/O
2.4 非 I/O的异步API是setTimeout()、setInterval()、 setImmediate()[该特性是非标准的,请尽量不要在生产环境中使用它!]和process.nextTick()
书中摘要:
1)因为在浏览器中JavaScript在单线程上执行, 而且它还与UI渲染共用一个线程。这意味着JavaScript在执行的时候UI渲染和响应是处于停滞状态的。
2)如果采用异步方式,第一个资源的获取并不会阻塞第二个资源,也即第二个资源的请求 并不依赖第一个资源的结束。如此,我们可以享受到并发的优势。
3)多线程的代价在于创建 线程和执行期线程上下文切换的开销较大。另外,在复杂的业务中,多线程编程经常面临锁、状 态同步等问题,这是多线程被诟病的主要原因。但是多线程在多核CPU上能够有效提升CPU的利用率,这个优势是毋庸置疑的。
4)单线程同步编程模型会因阻塞I/O导致硬件资源得不到更优的使用。多线程编程模型也因为 编程中的死锁、状态同步等问题让开发人员头疼
5)操作系统对异步I/O实现的支持状况
6)此处非阻塞I/O与阻塞I/O的区别在于阻塞I/O完成整个获取数据的过 程,而非阻塞I/O则不带数据直接返回,要获取数据,还需要通过文件描述符再次读取。
7)非阻塞I/O返回之后,CPU的时间片可以用来处理其他事务,此时的性能提升是明显的。 但非阻塞I/O也存在一些问题。由于完整的I/O并没有完成,立即返回的并不是业务层期望的数据,而仅仅是当前调用的状态。为了获取完整的数据,应用程序需要重复调用I/O操作来确认 是否完成。这种重复调用判断操作是否完成的技术叫做轮询
8)如何判断是否有事件需要处理呢?这里必须要引入的概念是观察者。每个事件循环中有一个或者多个观察者,而判断是否有事件要处理的过程就是向这些观察者询问 是否有要处理的事件。
9)在Node中,事件主要来源于网络请求、文件I/O等,这些事件对应的 观察者有文件I/O观察者、网络I/O观察者等。
10)在Windows下,则调用QueueUserWorkItem()方法将这个FSReqWrap对象推入 线程池中等待执行
11)事件循环、观察者、请求对象、I/O线程池这四者共同构成了Node异步I/O模型的基本要素。 Windows下主要通过IOCP来向系统内核发送I/O调用和从内核获取已完成的I/O操作,配以事件循环,以此完成异步I/O的过程。
12)定时器的问题在于,它并非精确的(在容忍范围内)。尽管事件循环十分快,但是如果某一 次循环占用的时间较多,那么下次循环时,它也许已经超时很久了。譬如通过setTimeout()设定一个任务在10毫秒后执行,但是在9毫秒后,有一个任务占用了5毫秒的CPU时间片,再次轮到定 时器执行时,时间就已经过期4毫秒。
