Appearance
NodeJS
NodeJS中的event loop和浏览器有什么区别?NodeJS作为服务有哪些优势?nginx反向代理?Koa的原理和中间件的实现?
参考:
NodeJS优缺点及应用场景
优点
- 基于事件模型,节省了为每一个请求建立连接的服务端资源,可以支持高并发
- 通过异步和回调实现非阻塞IO,在IO密集应用下很有用
缺点
- 不适合CPU密集型应用,长时间的计算会阻塞JavaScript执行异步任务
- 默认只支持单核
node核心内置类库
主要需要了解事件,流,文件,网络等模块的使用
EventEmitter
EventEmitter
提供了on
、once
、emit
、off
等方法,用于实现观察者模式,其主要功能是监听和发射消息,方便多个模块之间的通信
js
const EventEmitter = require("events");
const myEmitter = new EventEmitter();
// newListener是一个内部保留事件,当调用on方法添加事件处理函数时将触发该事件
// 可以用来做事件机制的反射,特殊应用,事件管理
myEmitter.once('newListener', (event, listener) => {
if (event === 'event') {
// Insert a new listener in front
myEmitter.on('event', () => {
console.log('B');
});
}
});
myEmitter.on('event', () => {
console.log('A');
});
myEmitter.emit('event');
// Prints:
// B
// A
此外需要注意的是:NodeJS监听事件时的错误处理风格一般是将err放事件处理函数的第一个参数,如
js
fs.stat('/tmp/world', (err, stats) => {
// 如果有错误则抛出异常
if (err) throw err;
// 没有错误则执行正常逻辑
console.log(`文件属性: ${JSON.stringify(stats)}`);
});
Stream
参考: Stream API
Node.js 提供了多种流对象,流可以是可读的、可写的、或者可读可写的,Stream
是 Node.js 中处理流式数据的抽象接口。
流的开发者可以声明一个新的 JavaScript 类并继承四个基本流类中之一(stream.Writeable、 stream.Readable、 stream.Duplex 或 stream.Transform),且确保调用了对应的父类构造器。
不同类型的流需要实现不同的方法,具体可以参考:用于实现流的 API
js
const { Writable } = require('stream');
class MyWritable extends Writable {
constructor(options) {
super(options);
// ...
}
_write(){}
_writev(){}
_final(){}
}
文件系统
参考:fs API
fs
模块提供了一个 API,用于以模仿标准 POSIX 函数的方式与文件系统进行交互。
操作文件一般有下面几种方式
- fs.open 方法,分配新的文件描述符。 一旦被分配,则文件描述符可用于从文件读取数据、向文件写入数据、或请求关于文件的信息。
- 通过流来操作文件,如fs.createReadStream用于从文件从文件中读取一定范围的字节而不是读取整个文件;fs.createWriteStream用于在文件开头之后的某个位置写入数据
- 通过fs模块提供的同步或异步方法操作文件,如
fs.readFile
和fs.readFileSync
,其中带Sync
后缀的接口表示同步操作
网络
参考
在Node.js的模块里面,与网络相关的模块有Net、DNS、HTTP、TLS/SSL、HTTPS、UDP/Datagram等,我们常用的应该是http
模块。
js
const http = require('http');
http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write('hello world');
res.end();
}).listen(3000); //绑定当前服务到3000端口
child-process
参考:
child_process
模块提供了衍生子进程的能力,子进程的运行结果储存在系统缓存之中(最大200KB),等到子进程运行结束以后,主进程再用回调函数读取子进程的运行结果。
NodeJS事件循环机制
参考:
在NodeJS中,事件循环可以分为几个阶段timer
、pending callbacks
、poll
等阶段,在每个阶段完成之后,才会清空微任务队列,然后执行下一个阶段的任务。
在v11
以后的版本中,为了与浏览器的事件循环保持一致,调整为每完成一个宏任务之后,就调用process._tickCallback()
清空微任务队列。
编写原生C++模块
参考:写一个N-API没那么难
Web开发
什么是Restful API ? koa和express有什么区别?中间件的作用是什么,能大概实现一下吗?你用过哪些模板引擎,他们有什么优劣?
Restful API
- Restful的意思就是表现层状态转化。
- "表现层"其实指的是"资源"(Resources)的"表现层",把"资源"具体呈现出来的形式,叫做它的"表现层"(Representation)。
- 所谓"资源",就是网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的实在,每一个URI代表一种资源。
- 果客户端想要操作服务器,必须通过某种手段,让服务器端发生"状态转化"(State Transfer)。而这种转化是建立在表现层之上的,所以就是"表现层状态转化"。
- Restful就是客户端和服务器之间,传递这种资源的某种表现层
- 客户端通过四个HTTP动词,对服务器端资源进行操作,实现"表现层状态转化"
- Restful API就是符合Restful架构的API设计。
中间件
app.use
中间件的原理是什么,我写了一个简单的实现 其原理就是维护一个中间件队列,每个中间件接收下一个中间件next
作为参数,并手动调用
express
Koa
模板引擎
参考