Node.js | 青训营笔记

62 阅读3分钟

这是我参与「第四届青训营 」笔记创作活动的第9天

Node.js

重点知识点介绍

  • Node.js 应用
  • Node.js 运行时结果
  • 编写 http server

详细知识点介绍

一、Node.js 的应用场景

  1. 前端工程化

    Node.js 地位难以被替代

  2. Web服务端应用

    学习曲线平缓,开发效率高,作为一门不需要编译的语言,运行效率较高,社区生态丰富(但相对于其他传统语言,相关包的成熟度可能不如),和前端结合的场景会有很大优势

  3. Electron 跨端桌面应用

    商业应用:vscode、slack

    大型公司的效率工具

    现状:大部分场景在选型时,都值得考虑

二、Node.js 的运行结构

image.png

Node.js 更多的代码是C++,图中的用户代码如 http server编写

结构特点:

  1. 异步 会在响应返回后恢复操作,而不是阻塞线程,在等待响应的时候可以做其他事情,内存占用更少
  2. 单线程 实际上是指JS的单线程,实际上是指JavaScript单线程,Node.js本身还是有很多线程。JS线程 + uv 线程 + V8 任务线程池 + V8 Inspector 线程。
  3. 跨平台 提供了统一的一套Api提供,来实现跨平台。大部分应用都可以包含,但仍有一些api是无法保证都有的,涉及底层的时候还是要自己设计。JS的无需编译和Node.js跨平台使得开发成本降低,整体学习成本低

三、编写 Http Server

1. 安装 Node.js

image.png

推荐大家使用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)
})

终端输出和浏览器访问结果

image.png

image.png

如果我要返回一段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的编写,有任何需要都可以在里面添加,定制化

刚才的例子中使用了许多回调函数,在很多场景中都有使用,但却不太好管理,因为回调函数并不知道什么时候会做,嵌套函数之间的关系不容易在代码中看出来,不好维护。

image.png

小结

Node.js 是基于服务端的语言,使得我们可以通过JavaScript来编写服务器,而对于需要独立运行的JS,nodejs就是一个解析器。Node.js对一些特殊用例进行优化,提供替代的API,使得V8在非浏览器环境下运行得更好,V8引擎执行Javascript的速度非常快,性能非常好,基于Chrome JavaScript运行时建立的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。