Node.js与前端开发|青训营笔记

109 阅读2分钟

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

Node.js的应用场景

  1. 前端工程化

在早期ajax,jquery比较流行的时候,我们可以直接在服务器加载lib进行开发。但随着后续模块化和transpile的日渐成熟,node.js逐渐显现出它允许开发者在浏览器外运行代码的优势,相比于过去的ajax等,催生出了很多esbuild,parcel这些工具。现阶段处于非常重要的地位,无法被取代。

  1. Web服务端应用

Node.js在Web服务端开发时的优势

  • 学习曲线平缓,开发效率高
  • 不需要编译环境,所以运行效率很高
  • 社区生态丰富,工具链成熟(npm,V8 inspector)
  • 与前端结合的场景会有优势(SSR)
  1. Electron跨桌面应用

例子:vscode、slack、discord、zoom或一些大型公司内的效率工具 Electron虽然有比较慢、资源消耗高的缺点,但是因为其是跨端的、运行稳定同时运行效率高的特点,还是值得尝试并使用的。字节跳动的飞书(Lark)就是一款Electron应用。

Node.js运行时的结构

总体来讲,我们可以把node.js运行时的结构总结为下图: Screenshot 2022-08-20 115638.jpg (引用自github.com/joyeecheung…)

特点

  1. 异步I/O
example.ts > ...
    setTimeout{() => {
        console.log('B')
    })
    cosole.log('A')

有关异步I/O的另一个例子是在读取文件call readFile()的时候,Node.js会被异步调用来处理请求。

优点:不会占用额外的内存,效率更高。

  1. 单线程
function fibonacci(num: number): number {
    if(num == 1 || num == 2) {
        return 1;
    }
    return fibonacci(num - 1) + fibonacci(num -2);
}

fibonacci(42)
fibonacci(43)

JS单线程:JS线程 + uv线程池 + V8任务线程池 + V8 Inspector线程

优点:不需要考虑多线程状态同步的问题,所以不需要锁;和异步I/O一样,可以更高效地利用资源

  1. 跨平台
TS example.ts > socket
    const net = require('net')
    
    const socket = new net.Socket('/temp/scoket.sock')

Node.js跨平台 + JS无需编译环境(+ Web跨平台 + 诊断工具跨平台)

优点:开发成本低;学习成本低

实践 - 编写Http Server

  1. 安装Node.js
  2. Http Server编写

server.js

const http = require('http')

const port = 3000

const server = http.createServer((req, res) => {
    res.end('Hello')
})

server.listen(port, () => {
    console.log('Listeningg= on: ${port}')
})

server_JSON.js

const server = htttp.createServer(req, res) => {
        const bufs = []
        // 将传输的数据储存到bufs中
        req.on('data', data => {
            bufs.push(data)
        })
        req.on('end', ()=> {
            let reqData = {}
            try {
                // 转化为字符串
                reqData = JSON.parse(Buffer.concat(bufs).toString())
             }catch {
                 // receive invalid jason data
                 res.end('invalid json')
             }
             res.setHeader('Content-Type', 'application/jason')
             res.end(JSON,stringify({
                 echo: reqData.msg || 'Hello',
             }))
            })
        })

client.js

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',
        'Content-Length': body.length,
    },
 }, (res) => {
     const bufs = []
     res.on('data', data => {
         bufs.push(data)
     })
     res.on('end', () =? {
         const receive = JSON.parse(Buffer.concat(bufs).toString()}
         console.log('receive: ", reveive)
      })
  })
  
  req.end(body)

promidify.js 用Promise + async wait重写这两个例子(将callback转成promise)

function wait(t) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve()
        }, t)
    })
}

wait(1000),then(() => {console.log{'get called'){)