这是我参与「第五届青训营 」伴学笔记创作活动的第8天
js必须在浏览器上运行,在电脑上配置js运行——nodejs
node应用场景
- web服务端
- electron跨端桌面应用(vscode/slack)
nodejs优势:
- 学习曲线平缓——有js基础
- 效率接近常见的编译语言
- 社区生态丰富及工具链成熟——与js用一套调试工具
- 与前端结合的场景有优势——SSR服务端渲染
node运行结构:
V8:js运行 libuv:事件循环
nodejs运行时结构特点:
- 异步 I/O——在响应返回后恢复操作,不是阻塞线程等待
- node是单线程的,可以使用worker_thread独立线程
- 跨平台
异步I/O优势——对资源利用率高,不会线程阻塞 js单线程(主线程是单线程)——js线程+uv线程池(http/)+V8任务线程池+V8 inspector线程(调试协议)
优势:不用考虑多线程状态同步,不需要锁;高效利用系统资源
node是跨平台的,上次api一致,自身针对不同操作系统调用不同
编写http Sever
const http = require('http')
//接收到http请求后触发匿名函数
const sever = http.createServer((req, res)=>{
const bufs = []
req.on('data', (buf)=>{
bufs.push(buf)
})
req.on('end', ()=>{
const buf = Buffer.concat(bufs).toString('utf-8')
const msg = 'hellow'
try{
const ret = JSON.parse(buf)
msg = ret.msg
}catch(err){
// res.end(invalid)
}
const responseJson = {
msg:`receive:${msg}`
}
res.setHeader('Content-Type', 'application/json')
res.end(JSON.stringify(responseJson))
})
// res.end('hello')
})
const port = 3001
//sever坚挺到端口后,调用函数
sever.listen(port, ()=>{
console.log('sever listen', port);
})
Promise
由于自己写回调函数,难以确认回调函数是否正确触发,不易维护,不好梳理处理关系=>Promise
——将callback形式代码写成Promise形式
新建promise类将原本的回调函数包裹起来 在promise中构建resolve方法,传入promise对象,即调用promise方法
const http = require('http')
//接收到http请求后触发匿名函数
const sever = http.createServer(async(req, res)=>{
const msg = await new Promise((resolve, reject)=>{
const bufs = []
req.on('data', (buf)=>{
bufs.push(buf)
})
req.on('end', ()=>{
const buf = Buffer.concat(bufs).toString('utf-8')
const msg = 'hellow'
try{
const ret = JSON.parse(buf)
msg = ret.msg
}catch(err){
// res.end(invalid)
}
})
resolve(msg);
})
const responseJson = {
msg:`receive:${msg}`
}
res.setHeader('Content-Type', 'application/json')
res.end(JSON.stringify(responseJson))
// res.end('hello')
})
const port = 3001
//sever坚挺到端口后,调用函数
sever.listen(port, ()=>{
console.log('sever listen', port);
})
静态文件服务
在 Node.js 中,读取文件的方式有两种,一种是用 fs.readFile ,另外一种是利用 fs.createReadStream 来读取。 是通过 Stream 来读取数据,它会把文件(数据)分割成小块,然后触发一些特定的事件,我们可以监听这些事件,编写特定的处理函数。这种方式相对上面来说,并不好上手,但它效率非常高。 Stream优于readFile方法
管道报错,暂时不知道怎么解决
const http = require('http')
const fs = require('fs')
const path = require('path')
const url = require('url')
const folderPath = path.resolve(__dirname, './static')
console.log(folderPath);
const filestream = fs.createReadStream('E:\\java\\html_project\\exp\\static\\index.html')
// console.log(filestream);
const server = http.createServer((req, res)=>{
console.log(req.url);
// const info = url.parse(req.url)
// console.log(info.path);
const filepath = path.resolve(folderPath,'./', 'index.html')
//E:\java\html_project\exp\static\字节.js
//e:\java\html_project\exp\static\字节.js
console.log(filepath);
const filestream = fs.createReadStream(filepath)
res.pipe(filestream)
})
const port = 3001
server.listen(port, ()=>{
console.log('listening on', port);
})
React SSR
server side rendering
SPA要去js加载好以后,再返回数据 ssr首屏渲染更快,SEO友好
缺点: 前端代码编写时需要考虑服务端渲染情况
难点:
- 处理打包代码——对浏览器无用
- 思考代码在服务端运行的逻辑
- 获取数据在挂载之后——不需要在一开始获取
nodejs调试
V8 Inspector