1. 控制台 #

在Node.js中,使用console对象代表控制台(在操作系统中表现为一个操作系统指定的字符界面,比如 Window中的命令提示窗口)。

2. 全局作用域 #

let test = function(){
  console.log('callback');
}
let timer = setInterval(test,1000);
timer.unref();
setTimeout(function(){
  timer.ref();
},3000)

3. 函数 #

4. process #

4.1 process对象 #

在node.js里,process 对象代表node.js应用程序,可以获取应用程序的用户,运行环境等各种信息

process.argv.forEach(function(item){
  console.log(item);
});
process.on('exit',function(){
  console.log('clear');
});

process.on('uncaughtException',function(err){
  console.log(err);
})

console.log(process.memoryUsage());
console.log(process.cwd());
console.log(__dirname);
process.chdir('..');
console.log(process.cwd());
console.log(__dirname);

function err(){
 throw new Error('报错了');
}
err();

4.2 process.nextTick & setImmediate #

setImmediate(function(){
  console.log('4');
});
setImmediate(function(){
  console.log('5');
});
process.nextTick(function(){
  console.log('1');
  process.nextTick(function(){
    console.log('2');
    process.nextTick(function(){
      console.log('3');
    });
  });
});

console.log('next');

5.Node中的Event Loop #

在libuv内部有这样一个事件环机制。在node启动时会初始化事件环

   
   ┌───────────────────────┐
┌─>│     timers(计时器)     │
|  |   执行setTimeout以及   |
|  |   setInterval的回调。  |
│  └──────────┬────────────┘
│  ┌──────────┴────────────┐
│  │     I/O callbacks     |
│  | 处理网络、流、tcp的错误 |
|  | callback              |
│  └──────────┬────────────┘
│  ┌──────────┴────────────┐
│  │     idle, prepare     │
|  |     node内部使用       |
│  └──────────┬────────────┘      
│  ┌──────────┴────────────┐       ┌───────────────┐ 
│  │       poll(轮询)      │       │   incoming:   │
|  | 执行poll中的i/o队列    | <─────┤  connections, │
|  | 检查定时器是否到时      |       │   data, etc.  |     
│  └──────────┬────────────┘       └───────────────┘    
│  ┌──────────┴────────────┐      
│  │      check(检查)      │
|  | 存放setImmediate回调   |
│  └──────────┬────────────┘
│  ┌──────────┴────────────┐
└──┤    close callbacks    |
   │ 关闭的回调例如         |
   | sockect.on('close')   |
   └───────────────────────┘

这里每一个阶段都对应一个事件队列,当event loop执行到某个阶段时会将当前阶段对应的队列依次执行。当队列执行完毕或者执行的数量超过上线时,会转入下一个阶段。这里我们重点关注poll阶段

5.1 poll阶段 #

poll 流程图

5.2 setTimeout 和 setImmediate #

二者非常相似,但是二者区别取决于他们什么时候被调用.

6.断点调试 #

6.1 命令行 #

V8 提供了一个强大的调试器,可以通过 TCP 协议从外部访问。Nodejs提供了一个内建调试器来帮助开发者调试应用程序。想要开启调试器我们需要在代码中加入debugger标签,当Nodejs执行到debugger标签时会自动暂停(debugger标签相当于在代码中开启一个断点)。

$ node inspect main.js
var a = 'a';
var b = 'b';

debugger;

var all = a + ' ' + b;
console.log(all);
命令 用途
c 继续执行到下一个断点处
next,n 单步执行
step,s 单步进入函数
out,o 退出当前函数
setBreakpoint(10),sb(10) 在第10行设置断点
repl 打开求值环境,ctrl_c退回debug模式
watch(exp) 把表达式添加监视列表
watchers 显示所有表达式的值

debugger

node浏览器调试 #

通过chrome浏览器进行调试

node --inspect-brk main.js

打开chrome 访问 chrome://inspect

vscode调试 #

配置debugger文件

{
    "type": "node",
    "request": "launch",
    "name": "my debugger",
    "program": "${file}",
    "cwd": "${cwd}"
}