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事件循环的理解相关推荐

  1. 为什么JS是单线程?JS中的Event Loop(事件循环)?JS如何实现异步?setimeout?

    https://segmentfault.com/a/1190000012806637 https://www.jianshu.com/p/93d756db8c81 首先,请牢记2点: (1) JS是 ...

  2. 理解node.js中的 Event Loop

    node中的 "event loop" 正是node能处理高并发的核心所在.也正是因为它,node虽然在本质上是个单线程,却能让大量的操作处于后台运行.这篇文章将详细说明 even ...

  3. Event Loop 事件循环简介

    1.Event Loop? Event Loop 其实也是在面试中经常会出现的一个题,前端程序员回答不上来是正常的,因为 Event Loop 是 C++ 实现的,实现原理和 JavaScript 没 ...

  4. Node.js文件的同步异步事件循环

    刚接触Node.js关于同步异步,事件循环的笔记: 1,文件同异步 var fs = require('fs'); fs.readFile('file.txt', 'utf-8', function( ...

  5. node mysql 事件循环_NodeJs 的 Event loop 事件循环机制详解

    什么是事件轮询 事件循环是 Node.js 处理非阻塞 I/O 操作的机制--尽管 JavaScript 是单线程处理的--当有可能的时候,它们会把操作转移到系统内核中去. 下面的图表显示了事件循环的 ...

  6. js 中的 Event Loop 以及 宏任务 与 微任务

    目录 前言 1.JS 的 执行引擎 与 执行环境 2.js 是单线程的 一.事件循环(Event Loop) 二.任务队列 三.宏任务 与 微任务 1.宏任务 2.微任务 3.宏任务与微任务的运行机制 ...

  7. Event Loop事件循环机制

    转载自:阮一峰博客<JavaScript 运行机制详解:再谈Event Loop> 一.为什么JavaScript是单线程? JavaScript语言的一大特点就是单线程,也就是说,同一个 ...

  8. JavaScript event loop事件循环 macrotask与microtask

    macrotask  姑且称为宏任务,在很多上下文也被简称为task.例如: setTimeout, setInterval, setImmediate, I/O, UI rendering. mic ...

  9. [译]理解js中的event loop

    之前看的文,感觉不太完整,于是找了篇详细的文章原文链接.翻译不正确的请指出,重在分享,如果有所收获就更好了. Javascript是如何异步和单线程的?简短的回答是javascript语言是单线程的, ...

最新文章

  1. CodeGen准备存储库
  2. Linux下截屏方法!
  3. 购物小票 FoundPrice.java
  4. 汇编 --- 从磁盘(扇区2到18)上读取数据到内存中
  5. Docker的基础命令
  6. php文件便利,PHP便利文件夹下所有文件,创建压缩包
  7. 【实例解析】某水泥企业应用商业智能提升管理效率
  8. python - - 函数 - - 递归函数
  9. Web.xml in Hello1 project
  10. PhotoShop如何给字体添加下划线
  11. 安装杀毒软件后计算机运行速度慢,我计算机安装杀毒软件后开机启动很慢
  12. Android WebView开发(三):WebView性能优化
  13. Win7局域网内找不到其他电脑怎么解决
  14. 142个手机短信笑话
  15. 极限编程-拥抱变化阅读感想(一)
  16. 爱思助手苹果服务器调整,爱思助手怎么改虚拟位置 爱思助手改虚拟位置方法...
  17. 【文献阅读】Commission Fee is not Enough: A Hierarchical Reinforced Framework for Portfolio Management
  18. 五 、Kotlin学习之命名参数默认参数
  19. Arcgis ArcTutor数据下载
  20. DynaBeanHolder动态bean构造器实现

热门文章

  1. Hexo安装配置详解
  2. 分块矩阵在秩不等式中的应用
  3. Lucene6.0 创建索引及查询text简单实例
  4. swift2.2的新特性
  5. IIS识别Json文件
  6. Nodejs基础中间件Connect
  7. 如何在SSIS的脚本组件中访问变量
  8. PLSQL_性能优化系列07_Oracle Parse Bind Variables解析绑定变量
  9. 导出EXCEL中的文件到资源管理器
  10. memmove() -- 拷贝内存内容