这是我参与「第五届青训营 」伴学笔记创作活动的第 7 天
重点内容:
- Node.js的应用场景
- Node.js运行时结构
- 编写Http Server
详细知识点:
一、应用场景
- 前端工程化
- Web 服务端应用 - 学习曲线平缓,开发效率高
- Electron 跨桌面应用
二、运行时结构
用户代码:由程序员编写的Javascript应用程序代码
V8:JavaScript Runtime,诊断调试工具(inspector)
libuv:eventloop(事件循环),syscall(系统调用)
例子:用node-fetch发起请求时
- 通过npm安装node-fetch模块
- 用户代码中调用node-fetch模块
- V8执行,在代码里可以fetch它在Node.js Core底层调用的http模块
- Node.js Core (JavaScript)中的http模块,去调用Node.js Core(C++) API
- 调用llhttp做http协议的序列化和反序列化
- 把得到数据通过libuv,调用创建tcp链接把数据发给远端
Node.js运行时结构特点:
- 异步I/O:适合I/O密集型应用
- 当Node.js执行I/O操作时,会在响应返回后回复操作。而不是阻塞线程并占用额外内存等待时间
- 单线程:不适合做CPU密集型应用
- 不用考虑多线程状态同步问题(不需要锁);同时还能比较高效地利用系统资源
- 阻塞会产生更多负面影响
- 跨平台
- Node.js跨平台+JS无需编译环境(+Web跨平台+诊断工具跨平台)=开发成本低(大部分场景无需担心跨平台问题),整体学习成本低
三、编写Http Server
JSON:
const http = require('http')
// 客户端传输的数据在req中,res可以把数据写回给另一端
const server = http.createServer((req, res) => {
const bufs = []
req.on('data', (buf) =>{
bufs.push(buf)
})
req.on('end', ()=>{
// bufs
const buf = Buffer.concat(bufs).toString('utf8')
let msg = 'hello'
try{
const ret = JSON.parse(buf)
msg = ret.msg
}catch (err) {
//
}
const responseJson = {
msg: `receive: ${msg}`
}
res.setHeader('Content-Type', 'application/json')
res.end(JSON.stringify(responseJson))
})
})
const port = 3000
server.listen(port, ()=> {
console.log('listening on: ', port)
})
Http Client
const http = require('http')
const body = JSON.stringify({
msg: 'Hello from my own client',
})
const req = http.request('http://127.0.0.1:3000', {
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)
React SSR
SSR (server side rendering)特点:
- 相比传统HTML模板引擎:避免重复编写代码
- 相比SPA(single page application):首屏渲染更快,SEO友好
- 缺点:通常qps较低,前端代码编写时需要考虑服务端渲染情况
*SSR需要处理打包代码
*需要思考前端代码在服务端运行时的逻辑
*移除对服务端无意义的作用,或重置环境
Debug
VS Inspector: 运行node --inspect
- 查看console.log内容
- breakpoint
- 高CPU,死循环:cpuprofile
- 高内存占用:heapsnapshot
- 性能分析