Node.js| 青训营笔记

54 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 7 天

1. Node.js的应用场景(why)

前端工程化、web服务端应用、Electron跨端桌面应用

2. Node.js运行时结构(what)

image.png ⭐⭐⭐面试:

  • 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底层,需要了解操作系统以及各种工具;需要经验