node
1. 什么是Node.js
一个基于Chrome V8引擎的JavaScript运行环境
使用事件驱动、非阻塞式I/O模型,使其轻量又高效(与阻塞I/O区别系统接收输入再到输出期间,能不能接收其他输入)
确定一个进行I/O的系统
思考在I/O过程中,能不能进行其他I/O
结论:在Chrome写JS控制浏览器,Node.js使用类似的方式控制计算机
2. CommonJS规范
3. node --help
4. npm
6. example
http-example.js
mock-event-emitter.js
read-file
read-file-sync.js
7. module
8. package
包在模块基础上更进一步抽象,NodeJS包类似于Java类库,它将某个独立功能封装起来,用于发布、更新、依赖管理、版本控制。NodeJS根据CommonJS规范实现了包机制,通过npm来解决包的发布和获取需求。
NodeJS包是一个目录,其中包含一个说明文件
package.json,严格符合CommonJS规范的包应具备这些特征:package.json必须放在包的根目录、二进制文件保存在bin目录、JavaScript代码保存在lib目录、文档放置在doc目录、单元测试保存在test目录。
9. build-in module
Console
Util
inherits()、inspect()、isXXX()Events
Event Emitter 的实例方法
EventEmitter.on(event, listener)/emitter.addListener(eventName, listener):为指定事件注册监听器,接受1个字符串事件名event和1个回调函数listenerEventEmitter.emit(event,[arg1],[arg2],[...]):发射event事件,传递若干可选参数到事件监听器的参数列表。EventEmitter.once(event, listener):为指定事件注册1个单次监听器,即该监听器最多只会触发一次,触发后立刻解EventEmitter.removeListener(event, listener):移除指定事件的某个监听器,listener必须是该事件已经注册过的监听器EventEmitter.removeAllListeners([event]):移除所有事件的所有监听器,如果指定event,则移除指定事件的所有监听器emitter.listenerCount(eventName)
File System (一般同步/异步两个版本)
简单文件读写
流式文件读写(大文件)
fs.createWriteStream()
pipe
rs.pipe(ws)some API
fs.open(path, flags[, mode], callback)
fs.read(fd, buffer, offset, length, position, callback)
fs.write(fd, buffer[, offset[, length[, position]]], callback)
fs.write(fd, string[, position[, encoding]], callback)
fs.close(fd, callback)
fs.existsSync(path)
fs.stat(path, callback)
fs.unlink(path, callback)
fs.readdir(path)
fs.truncate(path, len, callback)
fs.mkdir(path)
fs.rmdir(path)
fs.rename(oldPath, newPath, callback)
fs.watchFile(filename[, options][, listener])
fs.appendFile(file, data[, options], callback)
10. 模块加载机制
NodeJS模块分为是核心模块、文件模块:
核心模块:NodeJS标准API提供的模块(例如
fs、http、net、vm等),可以直接通过require 直接获取,例如require(‘fs’)。核心模块拥有最高的加载优先级,即如果有模块与其命名冲突,NodeJS总会优先加载核心模块文件模块:存储为单独文件或文件夹的模块(JavaScript代码、JSON、编译的C/C++代码)。文件模块的加载方法复杂但是灵活,尤其是与npm结合使用时。在不显式指定文件模块扩展名时,NodeJS会试图按不带扩展名、
.js、.json、.node扩展名顺序进行加载
文件模块加载方式
按路径加载(相对或绝对):如果require参数以/开头,就以绝对路径方式查找,例如
require(‘/hank/uinika’)将会按优先级依次尝试加载/hank/uinika.js、uinika.json、uinika.node。 如果以./或../开头,则以相对路径方式查找,例如require(‘./uinika’)用来加载相同文件夹下的uinika.js千万不要写成
require('xxx.js'), 其意思是加载核心模块查找node_modules加载:如果
require()函数参数不以/、./、../开头,该模块又不是核心模块,那么需要通过查找node_modules加载模块(npm获取的包就是以这种方式加载)。 例如node_modules目录之外的app.js可以直接使用require('express')代替require('./node_modules/express')。 当require()遇到一个既非核心模块,又不以路径表示的模块时,会试图在当前目录下的node_modules当中进行查找。如果没有找到,则会进入上一层目录的node_modules继续查找,直至遇到根目录
NodeJS模块不会被重复加载,因为NodeJS通过文件名缓存所有加载过的文件模块,再次访问时将不会重复加载
11. 循环中回调函数的陷阱
12. timer 异步
13. NodeJS的瓶颈
计算密集型程序 NodeJS不善于处理计算密集型应用,当事件回调函数需要进行复杂运算,那么事件循环中所有请求都要等待计算完成之后才能响应。解决这个问题,需要将复杂运算拆解成若干逻辑,但这样又会提高代码的复杂度。
单用户多任务型应用 单用户多任务的情况下,需要进程之间相互协作,NodeJS当中处理类似场景不方便。NodeJS多进程往往是在执行同一任务,通过多进程来利用多核处理器资源,但当遇到多进程需要相互协作的时候,就显得捉襟见肘。
逻辑复杂的事务 NodeJS的控制流被一个个事件拆散,是非线性的,但是人类思维是线性的,这样容易造成开发复杂度的提高。NodeJS更善于处理逻辑简单但访问频繁的任务,而不适合完成逻辑十分复杂的工作。
14. debug
vs-codeiron-nodesupervisornode --inspect index.js,点击chrome绿色node icon进入调试状态
Last updated