node.js中对Event Loop事件循环的理解
javascript是单线程的,所以任务的执行都需要排队,任务分为两种,一种是同步任务,一种是异步任务。
同步任务是进入主线程上排队执行的任务,上一个任务执行完了,下一个任务才会执行。
异步任务是不进入主线程,而是进入一个 "任务队列" 里,"任务队列" 通知主线程,该异步任务才会进入主线程执行。
任务的运行机制如下:
1、所有同步任务在主线程上执行,形成一个 "执行栈",注意栈是先进后出的。
2、主线程外,有一个 "任务队列" ,只要异步任务处理完有结果了,就在 "任务队列" 中放置一个事件,注意队列是先进先出的。
3、一旦 "执行栈" 中所有同步任务执行完毕。系统读取 "任务队列" 中的事件,对应的异步任务。放入 "执行栈" 中,开始执行。
4、主线程不断重复第三步,这种循环从 "任务队列" 中读取事件处理的这种运行机制称为Event Loop(事件循环)。
"执行栈" 中的同步代码总是比 "任务队列"中的异步任务之前运行。
function fun() {setTimeout(function () {console.log('异步任务');}, 0);console.log(1);console.log(2);console.log(3);console.log(4);console.log(5);
}
fun();
上面的代码,console.log代码写在setTimeout后面,但仍然先执行。
"任务队列" 是一个队列,队列的特性是先进先出。看下面代码:
function fun() {console.log(1);setTimeout(function () {console.log(2);setTimeout(function () {console.log(3);}, 0);}, 0);console.log(4);
}
fun();
输出结果为 1 4 2 3,打印 2 的setTimeout任务比打印 3 的setTimeout任务先进入队列,所以会先运行。
对于异步操作,像ajax,只有操作成功后返回结果,才会进入 "任务队列" 中,而不是调用的时候就放入队列中。看下面代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<script>function ajax() {var xhr = new XMLHttpRequest();xhr.open('GET', 'https://mail.163.com/', true);xhr.send();xhr.onreadystatechange = function () {if (xhr.readyState == 4 && xhr.status == 200) {console.log(xhr.responseText);}};}function fun() {console.log(1);ajax();setTimeout(function () {console.log(2);}, 1000);console.log(3);}fun();
</script>
</body>
</html>
ajax() 与 setTimeout 谁先进入队列,谁先输出,是需要看两者消耗时间,谁更短。时间短的会先进入队列先运行。
setTimeout 与 setInterval 运行机制一样,都是在指定时间把事件插入到 "任务队列" 尾部。区别是前者只执行一次,后者可反复执行。
node.js 还为我们提供了,process.nextTick 和 setImmediate 与 "任务队列" 有关的方法。
process.nextTick 会把回调函数放在当前 "执行栈" 的尾部。也就是说是在读取 "任务队列" 之前运行。
function fun() {console.log(1);setTimeout(function () {console.log(2);}, 0);process.nextTick(function () {console.log(3);process.nextTick(function () {console.log(4);});});process.nextTick(function () {console.log(5);});console.log(6);
}
fun();
上面的代码会输出 1 6 3 5 4 2 ,注意process.nextTick会把回调函数放在 "执行栈" 的尾部。
同步代码最先输出 1 6,然后 3 的先放入尾部,然后 5 的跟在 3 后面。3先执行,然后把 4 放入到 5 的后面。5执行完后,再执行4,最后读取 "任务队列" 中的输出2。
setImmediate 会把回调函数放在当前 "任务队列" 的尾部。也就是下一次事件循环Event Loop时执行。
function fun() {console.log(1);setTimeout(function () {console.log(2);}, 0);setImmediate(function () {console.log(3);});console.log(4);
}
fun();
上面的代码是会输出 1 4 2 3 还是 1 4 3 2 是不确定的,因为setTimeout 与 setImmediate 都会在下一次事件循环Event Loop中触发,所以输出是不确定的。
转载于:https://www.cnblogs.com/jkko123/p/10222859.html
node.js中对Event Loop事件循环的理解相关推荐
- 为什么JS是单线程?JS中的Event Loop(事件循环)?JS如何实现异步?setimeout?
https://segmentfault.com/a/1190000012806637 https://www.jianshu.com/p/93d756db8c81 首先,请牢记2点: (1) JS是 ...
- 理解node.js中的 Event Loop
node中的 "event loop" 正是node能处理高并发的核心所在.也正是因为它,node虽然在本质上是个单线程,却能让大量的操作处于后台运行.这篇文章将详细说明 even ...
- Event Loop 事件循环简介
1.Event Loop? Event Loop 其实也是在面试中经常会出现的一个题,前端程序员回答不上来是正常的,因为 Event Loop 是 C++ 实现的,实现原理和 JavaScript 没 ...
- Node.js文件的同步异步事件循环
刚接触Node.js关于同步异步,事件循环的笔记: 1,文件同异步 var fs = require('fs'); fs.readFile('file.txt', 'utf-8', function( ...
- node mysql 事件循环_NodeJs 的 Event loop 事件循环机制详解
什么是事件轮询 事件循环是 Node.js 处理非阻塞 I/O 操作的机制--尽管 JavaScript 是单线程处理的--当有可能的时候,它们会把操作转移到系统内核中去. 下面的图表显示了事件循环的 ...
- js 中的 Event Loop 以及 宏任务 与 微任务
目录 前言 1.JS 的 执行引擎 与 执行环境 2.js 是单线程的 一.事件循环(Event Loop) 二.任务队列 三.宏任务 与 微任务 1.宏任务 2.微任务 3.宏任务与微任务的运行机制 ...
- Event Loop事件循环机制
转载自:阮一峰博客<JavaScript 运行机制详解:再谈Event Loop> 一.为什么JavaScript是单线程? JavaScript语言的一大特点就是单线程,也就是说,同一个 ...
- JavaScript event loop事件循环 macrotask与microtask
macrotask 姑且称为宏任务,在很多上下文也被简称为task.例如: setTimeout, setInterval, setImmediate, I/O, UI rendering. mic ...
- [译]理解js中的event loop
之前看的文,感觉不太完整,于是找了篇详细的文章原文链接.翻译不正确的请指出,重在分享,如果有所收获就更好了. Javascript是如何异步和单线程的?简短的回答是javascript语言是单线程的, ...
最新文章
- CodeGen准备存储库
- Linux下截屏方法!
- 购物小票 FoundPrice.java
- 汇编 --- 从磁盘(扇区2到18)上读取数据到内存中
- Docker的基础命令
- php文件便利,PHP便利文件夹下所有文件,创建压缩包
- 【实例解析】某水泥企业应用商业智能提升管理效率
- python - - 函数 - - 递归函数
- Web.xml in Hello1 project
- PhotoShop如何给字体添加下划线
- 安装杀毒软件后计算机运行速度慢,我计算机安装杀毒软件后开机启动很慢
- Android WebView开发(三):WebView性能优化
- Win7局域网内找不到其他电脑怎么解决
- 142个手机短信笑话
- 极限编程-拥抱变化阅读感想(一)
- 爱思助手苹果服务器调整,爱思助手怎么改虚拟位置 爱思助手改虚拟位置方法...
- 【文献阅读】Commission Fee is not Enough: A Hierarchical Reinforced Framework for Portfolio Management
- 五 、Kotlin学习之命名参数默认参数
- Arcgis ArcTutor数据下载
- DynaBeanHolder动态bean构造器实现