node浅析

247 阅读3分钟

node runtime

  • 让js代码运行再服务端,node 基于v8 ,并不包含javascript 的全局。

  • DOM BOM ECMAScript

  • node中基本包含ECMAScript, 读写文件

  • 提供简单 高性能服务器 (cpu密集 计算 i/o密集 文件读取)

  • 分配单位 靠的是进程 进程是一个环境,环境中可以开很多线程(主线程是单线程,node api异步的)底层还是通过多线程来模拟了异步 libuv

  • 结果是靠事件驱动的

  • 浏览器 为什么不是多线程的,为了保存一致性,防止同时操作dom

  • java 多线程(切换执行上下文 切换的很快) 并发操作同一个文件 锁的概念

  • 多进程 增强稳定性 可靠性

node

  • 异步/同步 被调用方 可以决定此方法是 同步还是异步的
  • 阻塞/非阻塞 调用方的状态决定阻塞/非阻塞 同步阻塞,异步非阻塞

node 事件环(event loop)

  • 主执行栈
  • 微任务 (promise.then < process.nextTick) 只要队列发生切换时就会执行微任务
  • timers 时间 setTimeout的回调
  • poll 轮询 i/o 回调 fs.readFile()
  • check setImmediate 方法

默认 会从上到下依次执行 如果代码执行到poll发现check阶段没有,就在poll中等待时间到达后再清空代码。

切换队列把队列清空,如果执行了很多个回调,超过最大限制也会切换队列 poll阶段下一个阶段是check 如果check队列中有东西,会先执行check

node 11 有更新 目测 (宏任务执行一个就会执行微任务(更像浏览器))新版中每个宏任务执行后就会清空微任务

commonjs require 方法的实现

  • 内置实现了一个require方法
  • 通过Module._load 方法 加载模块
  • Module._resolveFilename 根据相对路径换化为绝对路径 并且增加后缀
  • 模块的缓存问题 Module._cache[filename]
  • new Module 创建一个模块 id 存的是名字 exports = {} this
  • tryModuleLoad尝试加载模块
// global 可以直接访问global 并且没有window的概念。 =>this(文件中打印)=>{}
//window 代理了global

//process进程(当前运行的环境)
//Buffer 读取的内容 都是二进制 buffer主要是内存 缓存 16进制 可以和字符串相互转化。
//clearImmediate setImmediate 宏任务
//clearInterval setTimeout 宏任务
//clearTimeout setInterval

// console.log(global,{showHidden:true});
console.log(setTimeout===global.setTimeout);//true
console.log(this);//node的文件 默认在外面套了一层函数,在函数运行时把this指向改变了。
//repl  read-eval-print-loop

process.cwd();  //current working directory 当前工作目录
process.env;    //envirment 环境
process.argv;   //arguments  参数
process.nextTick;//下一队列  微任务

console.log(process.cwd()); //在哪执行文件,就可以打印出位置 *
//webpack 开发环境(process.env.NODE_ENV) 生产环境
//window set a=1 mac export a=1
console.log(process.env);
if(process.env.NODE_DEV==='production'){
  console.log('生产环境');
}else{
  console.log(32)
}
//mockjs

let args = process.argv.slice(2);  //['--port','3000']
let obj = {};
for(let i=0;i<args.length;i++){
  let current = args[i];
  if(current.includes('--')){
    obj[current.slice(2)] = args[i+1];
  }
}
console.log(obj.port);


Promise.resolve().then(()=>{
  console.log('then');
})
process.nextTick(function(){
  console.log('nextTick');
})

nodeEventLoop

setTimeout(()=>{
  console.log('timeout1');
  process.nextTick(()=>{
    console.log('nextTick2');
  });
});
console.log('start');
process.nextTick(()=>{
  console.log('nextTick1');
  setTimeout(()=>{
    console.log('timeout2');
  });
})

//node 10
// start nextTick timeout1 nextTick2 timeout2

//node 11 尽量和浏览器的表现相同
setImmediate(()=>{ //check
  console.log('setImmediate');
});
setTimeout(()=>{ //timer
  console.log('setTimeout');
})

let fs = require('fs');
fs.readFile('./name.txt','utf-8',()=>{
  setImmediate(()=>{
    console.log('setImmediate');
  });
  setTimeout(()=>{
    console.log('timeout');
  });
})