这是我参与「第四届青训营 」笔记创作活动的第9天
Node.js
重点知识点介绍
- Node.js 应用
- Node.js 运行时结果
- 编写 http server
详细知识点介绍
一、Node.js 的应用场景
-
前端工程化
Node.js 地位难以被替代
-
Web服务端应用
学习曲线平缓,开发效率高,作为一门不需要编译的语言,运行效率较高,社区生态丰富(但相对于其他传统语言,相关包的成熟度可能不如),和前端结合的场景会有很大优势
-
Electron 跨端桌面应用
商业应用:vscode、slack
大型公司的效率工具
现状:大部分场景在选型时,都值得考虑
二、Node.js 的运行结构
Node.js 更多的代码是C++,图中的用户代码如 http server编写
结构特点:
- 异步 会在响应返回后恢复操作,而不是阻塞线程,在等待响应的时候可以做其他事情,内存占用更少
- 单线程 实际上是指JS的单线程,实际上是指JavaScript单线程,Node.js本身还是有很多线程。JS线程 + uv 线程 + V8 任务线程池 + V8 Inspector 线程。
- 跨平台 提供了统一的一套Api提供,来实现跨平台。大部分应用都可以包含,但仍有一些api是无法保证都有的,涉及底层的时候还是要自己设计。JS的无需编译和Node.js跨平台使得开发成本降低,整体学习成本低
三、编写 Http Server
1. 安装 Node.js
推荐大家使用nvm工具,能够方便管理node.js的版本,在开发中会涉及到各种版本的切换
2. 编写一个简单的 server(无框架)
框架有好有坏,有框架可以快速开发,但全都通过框架做,对于定制性需求无法满足,需要对原生的东西要有了解,对原生提供的模块要有一些了解,未来使用框架出现问题时也好做排查
const http = require('http')
// 服务器,包含一个回调函数
const server = http.createServer((req,res)=>{
res.end('hello')
})
const port = 3000
// listen的作用是当server成功监听到端口后,就会触发这个回调函数,表示监听成功
server.listen(port, () => {
console.log('listen on ',port)
})
终端输出和浏览器访问结果
如果我要返回一段Json数据的话,则
// 编写服务器,返回一段json数据
const http = require('http')
// 服务器,包含一个回调函数
const server = http.createServer((req,res)=>{
const bufs = []
// 绑定data事件
req.on('data', (buf) => {
bufs.push(buf)
})
req.on('end', () => {
const buf = Buffer.concat(bufs).toString('utf-8')
let msg = 'Hello'
try {
const ret = JSON.parse(buf)
msg = ret.msg
} catch (err) {
// res.end('invalid json')
}
const responseJson = {
msg: `receive: ${msg}`
}
res.setHeader('Content-Type','application/json')
res.end(JSON.stringify(responseJson))
})
})
const port = 3000
// listen的作用是当server成功监听到端口后,就会触发这个回调函数,表示监听成功
server.listen(port, () => {
console.log('listen on ',port)
})
通过浏览器去访问实际上没有给server传数据,是伪造的数据。这里编写一段客户端的代码,模拟请求post传数据(因为一般get请求在很多实现里是不能请求 http server的)
客户端代码
const http = require('http')
const body = JSON.stringify({
msg: 'Hello from my own client',
})
http.request('URL',{
method: 'POST',
headers: {
'Content-Type':'application/json'
}
},(res)=>{
const bufs = []
res.on('data',(buf) => {
bufs.push(buf)
})
res.on('end', () => {
const buf = Buffer.concat(bufs)
const json = JSON.parse(buf)
console.log('json.msg is:',json.msg)
} )
})
req.end(body)
这样就完成了原生的http server的编写,有任何需要都可以在里面添加,定制化
刚才的例子中使用了许多回调函数,在很多场景中都有使用,但却不太好管理,因为回调函数并不知道什么时候会做,嵌套函数之间的关系不容易在代码中看出来,不好维护。
小结
Node.js 是基于服务端的语言,使得我们可以通过JavaScript来编写服务器,而对于需要独立运行的JS,nodejs就是一个解析器。Node.js对一些特殊用例进行优化,提供替代的API,使得V8在非浏览器环境下运行得更好,V8引擎执行Javascript的速度非常快,性能非常好,基于Chrome JavaScript运行时建立的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。