这是我参与「第四届青训营」笔记创作活动的的第2天
Node.js的应用场景
- 前端工程化
在早期ajax,jquery比较流行的时候,我们可以直接在服务器加载lib进行开发。但随着后续模块化和transpile的日渐成熟,node.js逐渐显现出它允许开发者在浏览器外运行代码的优势,相比于过去的ajax等,催生出了很多esbuild,parcel这些工具。现阶段处于非常重要的地位,无法被取代。
- Web服务端应用
Node.js在Web服务端开发时的优势
- 学习曲线平缓,开发效率高
- 不需要编译环境,所以运行效率很高
- 社区生态丰富,工具链成熟(npm,V8 inspector)
- 与前端结合的场景会有优势(SSR)
- Electron跨桌面应用
例子:vscode、slack、discord、zoom或一些大型公司内的效率工具 Electron虽然有比较慢、资源消耗高的缺点,但是因为其是跨端的、运行稳定同时运行效率高的特点,还是值得尝试并使用的。字节跳动的飞书(Lark)就是一款Electron应用。
Node.js运行时的结构
总体来讲,我们可以把node.js运行时的结构总结为下图:
(引用自github.com/joyeecheung…)
特点
- 异步I/O
example.ts > ...
setTimeout{() => {
console.log('B')
})
cosole.log('A')
有关异步I/O的另一个例子是在读取文件call readFile()的时候,Node.js会被异步调用来处理请求。
优点:不会占用额外的内存,效率更高。
- 单线程
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一样,可以更高效地利用资源
- 跨平台
TS example.ts > socket
const net = require('net')
const socket = new net.Socket('/temp/scoket.sock')
Node.js跨平台 + JS无需编译环境(+ Web跨平台 + 诊断工具跨平台)
优点:开发成本低;学习成本低
实践 - 编写Http Server
- 安装Node.js
- 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'){)