# 基本

  • node 是基于事件驱动的异步操作架构,内置events
  • 用到的很多内置模块其实都继承了 eventemitter

# Event Loop

会另外花个篇幅去讲

# 总图

  • 同步代码,遇到异步就放进对应的队列
  • 同步完成先执行微任务如 promise,微任务清空就去事件队列
  • 这些为事件队列 timers - pending callback - idle, prepare - poll - check - close callbacks - backto timers
  • 事件队列每次切换都回去清空一次微任务

# 微任务

  • 不是队列,有优先级
  • promise
  • process.nexttick 高于 promise (no why)

# 事件队列说明

  • timers 执行settimeout/setinterval回调
  • pending callback 操作系统的回调 tcp/udp
  • idle, prepare 系统内部
  • poll i/o相关
  • check setimmediate
  • close callbacks 执行与close事件的回调

# 异步io

  • 阻塞io/非阻塞io,底层会重复(轮询)调用io操作确认io是否结束,对于代码还是同步
  • 期望 无需要主动判断的非阻塞io

# libuv

  • 几种不同的异步io实现方式的抽象封装层
  • 运行->libuv->根据平台去调用底层
  • 里面有线程池
  • node运行-异步部分-event loop-io处理-底层io接口-事件队列(event queue)-event loop
  • 其实还是应用异步循环机制加进去

# 事件

  • 通过回调的方式走事件驱动
  • on/emit/once/off
const eventemitter = require('events')
const myevent = new eventemitter()
myevent.on('yiki1'),()=>{
  ...
}
myevent.on('yiki1'),()=>{ // 可以多个同名,按照注册顺序
  ...
}
myevent.emit('yiki1')

# http

const http = require('http')
const serve = http.creatserver(req,res=>{
  res.send(..)
  let {pathname,query} = url.parse(req.url,true)
  // req.header
  // req.method
})
serve.listen(9999,()=>{
  ...
})

# node的高并发

  • 主线程是单线程
  • 异步非阻塞io配合事件回调通知去实现
  • libuv库里面有很多处理线程和线程池帮助实现高并发

# express

import express from 'express'
const app = express()
app.get('/eee/,(req,res)=>{
return sth
})
app.listen(9999,(req,res)=>{
  res.end('de')

  ...
})

# globle

全局对象

  • __filename 绝对路径
  • __dirname 正在执行脚本所在目录
  • timer类
  • process 和当前进程进行互动
  • require 是拷贝
  • module、exports

# process

  • version
  • arch
  • platform
  • pid
  • on/before/stdout
process.on('exit',(code)=>{
...只能同步
})
process.on('before',(code)=>{
... 异步+同步,但是写异步会不断循环
})
process.exit()
// 重写log
console.log = function(data){
  process.stdout.write('----'+data)
}

# pipe

process.stdin.pipe(process.stdout)
// 控制台输入什么就重复什么

# path

内置,用require,资源路径拼接

  • resolve(from,to) 返回绝对路径
  • pasre() 解析
  • format() 序列号路径
  • normalize() 规范化路径
  • join

# buffer

缓冲区,操作二进制,stream(可以用pipe)

  • alloc 指定字节的buffer
  • from 接收数据来创建buffer
  • fill
  • write 写入
  • tostring 从里面提取
  • slice 截取
  • concat

# fs

提供文件系统操作的api,内置,操作文件里面的二进制数据

  • readfile 配合path.resolve
  • writefile
  • appendfile
  • copyfile
  • watchfile
  • open 大文件用 利用buffer
  • write 配合open边读边写
  • close

# md转html

  • 样式/第三方包/占位符
  • 读取md+css替换html里面的占位符
  • 监听 md 变化,更新html
const fs = require('fs')
const path = require('path')
const marked = require('marked')
const name = require('browser-sync') // 实时显示html

const temp = `html+{{占位符}}`
let mypath = path.join(__dirname, process.argv[2])
let csspath = path.resolve('xx.css')
let htmlpath = mypath.replace(path.extname(mypath),'.html')

// 监听
fs.watchfile(mypath,(curr,prev)=>{
  //判断是否一致
  if(curr.mtime!==prev.mtime){

  fs.readfile(mdpath,'utf-8',(err,data)=>{
  let htmlstr = marked(data)
  fs.readfile(csspath,'utf-8',(err,data)=>{
    let rethtml = temp.repalce('{{content}}',htmlstr).repalce({{style}},data)
    fs.writefile(htmlpath,retphtml,err=>{
      //success
    })
  })
})}
})
browsersync.init({
  brower:'',
  server:__dirname,
  watch:true,
  init
})

# 定位顺序

  • .js-.json-.node/index

# vm

  • 创建独立运行的沙箱环境,拿来运行不是js代码的东西
  • 内置,require('vm')
  • fs + eval , 不能重名
  • new function
  • 用vm沙箱 ,能拿到全局变量
vm.runinthiscontext(content)

# 发布订阅模式

  • 回调嵌套垃圾
  • 存在一个调度中心,观察者模式里面是没有的
  • 状态发生改变的时候不是发布者去主动通知的,而是通过调度中心去做的
  • 订阅者n个 - 想监听的事件注册到-> 消息调度中心(event loop) <-发布者
class pubsub{
  constructor(){
    this._events = {}
  }
  // 注册
  subscribe(event, callback){
    if(this._event[event]){
      this._events[event].push(callback)
    }else{
      this.events[ecent]= [callback]
    }
  }

  publich(event,...args){
    const items = this._events[event]
    if(items&&item.length){
      items.foreach(function(callback){
        callback.call(this,...args)
      })
    }
  }
}

let ps = new pubsub()
ps.subscribe('yiki',()=>{
  //注册不执行
})
ps.publich('yiki')// 执行

# net 网络通信

  • listening
  • connection
  • close
  • error
  • data 可读流拿数据操作
  • write 在socket上发送数据
  • end socket发送fin包

# tcp连接

双工流

  • server
const net = require('net')

const server = net.createserver()
const port = 1223
server.listen(port,host)
server.on('listening',()=>{
  console.log('server is starting..')
})
server.on('connnetion',(socket)=>{
  socket.on('data',(chunk)=>{
    const msg = chunk.tostring()
    socket.write(buffer.from('hi'))
  })
})
  • client
const net = require('net')

const client = net.creatconnection({
  port:1223
  host:
})
client.on('connect',()=>{
  client.write('test')
})

# 数据粘包

用settimeout

Last Updated: 2022/6/26 上午11:43:14