Node.js学习总结-----事件循环
1.介绍
事件循环机制是Node.js最重要的一部分之一。
为什么他这么重要呢?因为它解释了为什么Node.js(单线程)可以是异步的,并且不会阻塞IO。
Node.js可以做到这些,离不开调用栈、消息队列和ES6工作队列。
2.调用栈
在执行javascript脚本的时候会顺序执行,讲执行的函数按照顺序入栈,执行完之后退出栈。
例子如下:
test1() {
console.log('test1');
}
test2() {
console.log('test2');
}
test3() {
console.log('test3 start');
test1();
test2();
console.log('test3 end');
}
test3();
执行这个脚本会得到如下结果:
test3 start
test1
test2
test3 end
调用栈按照一下顺序调用:
1.调用test3()
|__test3__|2.执行test3()
|__console.log("test3 start")__|3.test1()入栈并执行
|__________test3___________ |
|__console.log("test1")__|test1执行完之后退栈
|______test1___________|
|______test3___________|
4.test2()入栈并执行
|__console.log("test2")__|test2执行完之后退栈
|______test2___________|
|______test3___________|
5.继续执行test3
|__console.log("test3 end")__|test3执行完之后退栈
|__________test3___________|
3.消息队列 如果只使用一个调用栈,那么当一个函数执行时间很长时,这个函数会阻塞后面的需要被调用的函数。
因此,将那些会阻塞其他正常函数执行的函数(用户发起的事件)放在消息队列中,如定时器、单击或键盘事件、Dom事件。
例子:
test1() {
console.log('test1');
}
test2() {
console.log('test2');
}
test3() {
setTimeOut(()=> console.log('last'),0);
test1();
test2();
console.log('test3 end');
}
test3();
执行这个脚本会得到如下结果:
test1
test2
test3 end
last
执行过程如下:
1.执行test3()并入栈
|__test3__|2.执行setTimeOut并入队列
栈:3.test1()入栈并执行
|__setTimeOut(xxx)__|
|_____test3_________|
队列:
| console.log('last') |
|__console.log("test1")__|【Node.js学习总结-----事件循环】test1执行完之后退栈
|______test1___________|
|______test3___________|
4.test2()入栈并执行
|__console.log("test2")__|test2执行完之后退栈
|______test2___________|
|______test3___________|
5.继续执行test3
|__console.log("test3 end")__|test3执行完之后退栈
|__________test3___________|
6.栈空之后执行消息队列内容
队列:这个线程会先去执行调用栈,调用栈空之后心才会去执行消息队列中的内容。
| console.log('last') |
4.ES6工作队列 ECMAScript 2015 / ES6 引进的工作队列的概念,这个工作队列会将promise放进去。
消息队列和工作队列之间的关系可以用在游乐园坐过山车来比喻:
消息队列把你放在队列的后面,在所有其他人的后面,你必须在那里等待轮到你,而工作队列是快速通行证 这样您就可以在完成上一次骑行后立即进行另一次骑行。
例子:
test1() {
console.log('test1');
}
test2() {
console.log('test2');
}
test3() {
setTimeOut(()=> console.log('last'),0);
new Promise((resolve,reject)=>{
resole('before last');
}).then(res => console.log(res));
test1();
test2();
console.log('test3 end');
}
test3();
执行这个脚本会得到如下结果:
test1
test2
test3 end
before last
last
执行过程如下:
1.执行test3()并入栈
|__test3__|2.执行setTimeOut并入消息队列
栈:3.执行promise并入工作队列
|__setTimeOut(xxx)__|
|_____test3_________|
消息队列:
| console.log('last') |
栈:4.test1()入栈并执行
|__resole(xxx)_______|
|_____test3_________|
工作列:
| console.log('before last') |
|__console.log("test1")__|test1执行完之后退栈
|______test1___________|
|______test3___________|
5.test2()入栈并执行
|__console.log("test2")__|test2执行完之后退栈
|______test2___________|
|______test3___________|
6.继续执行test3
|__console.log("test3 end")__|test3执行完之后退栈
|__________test3___________|
7.栈空之后执行消息队列内容
队列:8.栈空之后执行工作队列内容
| console.log('last') |
队列:
| console.log('before last') |
推荐阅读
- 由浅入深理解AOP
- 7.9号工作总结~司硕
- 继续努力,自主学习家庭Day135(20181015)
- python学习之|python学习之 实现QQ自动发送消息
- 一起来学习C语言的字符串转换函数
- Node.js中readline模块实现终端输入
- 定制一套英文学习方案
- 漫画初学者如何学习漫画背景的透视画法(这篇教程请收藏好了!)
- 《深度倾听》第5天──「RIA学习力」便签输出第16期
- 如何更好的去学习