这是我参与「第五届青训营 」伴学笔记创作活动的第 7 天
1. Node.js的应用场景(why)
前端工程化、web服务端应用、Electron跨端桌面应用2. Node.js运行时结构(what)
⭐⭐⭐面试:
- V8: JavaScript Runtime,诊断调试工具(inspector)
- libuv: eventloop (事件循环),syscall (系统调用)
- 举例:用node- fetch发起请求时.
特点:
- 异步I/O(不阻塞线程,而是去做其他的操作)
- 单线程:实际:JS线程+uv线程池+V8任务线程池+V8Inspector线程;不需要考虑同步、死锁,但会有阻塞问题
- 跨平台:开发成本低、学习成本低
3. 编写Http Server (how)
const { request, createServer } = require("http");
const http = require('http')
const port = 3000
const serve = createServer((req,res)=>{//req:客户端传回来的数据,res:我要写回的数据
res.end('Hello!')
})
serve.listen(port,()=>{
console.log('listening on:', port);
})
const { request, createServer } = require("http");
const http = require('http')
const port = 3000
const serve = createServer((req,res)=>{//req:客户端传回来的数据,res:我要写回的数据
bufs = []
req.on('data',(buf)=>{
bufs.push(buf)
})
req.on('end',()=>{
const buf = Buffer.concat(bufs).toString('utf-8')//buffer专门存放二进制数据的缓存区
let msg = 'hello'//let与var类似,但let只在声明的代码块里有效
try{
const ret = JSON.parse(buf)//JSON 通常用于与服务端交换数据, JSON.parse() 方法将数据转换为 JavaScript 对象
msg = ret.msg
}catch (err){
//
}
const responsejson = {
msg: `receive: ${msg}`
}
res.setHeader('Content-Type','application/json')
res.end(JSON.stringify(responsejson))//将某个对象转换成 JSON 字符串形式
})
})
serve.listen(port,()=>{
console.log('listening on:', port)
})
const http = require('http')
const body = JSON.stringify({
msg:'Hello from my 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)
这里服务器仍然显示hello,终端呈现json.msg is receive: Hello from my client
其中对于服务器端的接受msg,可以单独写成一个函数,增加可读性
const { request, createServer } = require("http");
const http = require('http');
const { rejects } = require("assert/strict");
const port = 3000
const serve = createServer(async (req,res)=>{//req:客户端传回来的数据,res:我要写回的数据
const msg = await new Promise((resolve,reject) => {
const bufs = []
req.on('data',(buf)=>{
bufs.push(buf)
})
req.on('error',(err)=>{
reject(err)
})
req.on('end',()=>{
//receive body from client
const buf = Buffer.concat(bufs).toString('utf-8')//buffer专门存放二进制数据的缓存区
let msg = 'hello'//let与var类似,但let只在声明的代码块里有效
try{
const ret = JSON.parse(buf)//JSON 通常用于与服务端交换数据, JSON.parse() 方法将数据转换为 JavaScript 对象
msg = ret.msg
}catch (err){
//
}
resolve(msg)
})
})
//respond
const responsejson = {
msg: `receive: ${msg}`
}
res.setHeader('Content-Type','application/json')
res.end(JSON.stringify(responsejson))//将某个对象转换成 JSON 字符串形式
})
serve.listen(port,()=>{
console.log('listening on:', port)
})
SSR (server side rendering)有什么特点?
- 相比传统HTML模版引擎:避免重复编写代码
- 相比SPA (single page application) : 首屏渲染更快,SEO 友好
- 缺点:通常qps较低,前端代码编写时需要考虑服务端渲染情况 SSR难点:
- 需要处理打包代码
- 需要思考前端代码在服务端运行时的逻辑
- 移除对服务端无意义的副作用,或重置环境 部署要解决的问题
- 守护进程:当进程退出时,重新拉起
- 多进程: cluster 便捷地利用多进程
- 记录进程状态,用于诊断
容器环境:通常有健康检查的手段,只需考虑多核cpu利用率即可
4. 延伸话题
- 诊断是个低频、重要同时也相当有挑战的方向。是企业衡量自己能否依赖一门语言的重要参考。
- 技术咨询行业中的热角色。
- 难点:需要了解Node.js底层,需要了解操作系统以及各种工具;需要经验