JS事件循环机制event loop宏任务微任务原理解析
首先看一段代码
async function (){ await f2() console.log('f1') } async function f2(){ console.log('f2') } console.log('正常1') f1() setTimeout(()=>{ console.log('定时器') }) console.log('正常2')
正确的打印顺序应该是:正常1,f2 ,正常2,f1,定时器
为什么会出现这样打印顺序呢
首先javascript是一门单线程语言,在最新的HTML5中提出了Web-Worker,但javascript是单线程这一核心仍未改变。既然js是单线程,那就像只有一个窗口的银行,客户需要排队一个一个办理业务,同理js任务也要一个一个顺序执行。如果一个任务耗时过长,那么后一个任务也必须等着。所以就出现了同步任务和异步任务。
概念
除了广义的同步任务和异步任务,对任务可以进行更精细的区分
- macro-task(宏任务):包括整体代码script,setTimeout,setInterval
- micro-task(微任务):Promise,process.nextTick
宏任务:浏览器为了能够使得JS内部task与DOM任务能够有序的执行,会在一个task执行结束后,在下一个 task 执行开始前,对页面进行重新渲染 (task->渲染->task->…)
鼠标点击会触发一个事件回调,需要执行一个宏任务,然后解析HTMl
微任务:微任务通常来说就是需要在当前 同步任务 执行结束后立即执行的任务,比如对一系列动作做出反馈,或者是需要异步的执行任务而又不需要分配一个新的任务,这样便可以减小一点性能的开销。
既然我们清楚了概念,我们再看一遍代码
async function (){ await f2() console.log('f1') } async function f2(){ console.log('f2') } console.log('正常1') f1() setTimeout(()=>{ console.log('定时器') }) console.log('正常2')
执行顺序
首先我们进行正常的同步流程,打印出‘正常1',接下来执行f1()函数,await后面的函数f2()会立即执行,所以会打印'f2',继续执行同步代码打印‘正常2',至此同步任务全部结束,开始执行异步任务微任务,await f2()等待f2()方法执行完之后打印出f1,最后执行宏任务setTimeout打印‘定时器'
这就是为什么‘正常1',正常2'会打印在‘f1'之前,因为所有微任务执行的时候,当前执行栈的代码必须已经执行完毕。‘f2','f1'会打印在‘定时器'之前是因为所有微任务总会在下一个宏任务之前全部执行完毕
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
相关推荐
-
JavaScript Event Loop相关原理解析
1.单线程模型 单线程模型指的是,JavaScript只能在一个线程上运行,也就是说只能同时指向一个任务,其他任务都必须在后面排队等待.注意:虽然JavaScript只在一个线程上运行,但并不代码JavaScript引擎只有一个线程.事实上,JavaScript引擎有多个线程,单个脚本只能在一个线程上运行(主线程),其他线程都是在后台配合. JavaScript为什么要采用单线程,而不是多线程? 不想让浏览器变得复杂(避免复杂性),因为多线程需要共享资源.且可能修改彼此运行的结果. 该模式会导致
-
JavaScript运行机制之事件循环(Event Loop)详解
一.为什么JavaScript是单线程? JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事.那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊. JavaScript的单线程,与它的用途有关.作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM.这决定了它只能是单线程,否则会带来很复杂的同步问题.比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线
-
Node.js事件循环(Event Loop)和线程池详解
Node的"事件循环"(Event Loop)是它能够处理大并发.高吞吐量的核心.这是最神奇的地方,据此Node.js基本上可以理解成"单线程",同时还允许在后台处理任意的操作.这篇文章将阐明事件循环是如何工作的,你也可以感受到它的神奇. 事件驱动编程 理解事件循环,首先要理解事件驱动编程(Event Driven Programming).它出现在1960年.如今,事件驱动编程在UI编程中大量使用.JavaScript的一个主要用途是与DOM交互,所以使用基于事件
-
前端js中的事件循环eventloop机制详解
前言 我们知道 js 是单线程执行的,那么异步的代码 js 是怎么处理的呢?例如下面的代码是如何进行输出的: console.log(1); setTimeout(function() { console.log(2); }, 0); new Promise(function(resolve) { console.log(3); resolve(Date.now()); }).then(function() { console.log(4); }); console.log(5); setTim
-
JavaScript中EventLoop介绍
想象下,比如浏览器在运行一个复杂的图像转换算法,因为是单线程的,所以此时浏览器进程被阻塞了,不能进行界面渲染,也不能运行其他代码,你的应用界面会失去和用户的交互. 这一般情况下还不会有大问题,但是当浏览器在同时运行多个类似的算法时,这个问题就很严重了. 有一定经验js开发人员大多都理解代码的异步执行,特别是ajax的使用. // ajax(..) is some arbitrary Ajax function given by a library var response = ajax('htt
-
Node.JS中事件轮询(Event Loop)的解析
当我们知道I/O操作和创建新线程的开销是巨大的! 网站延迟的开销 对于一个网站,后台大多不需要进行复杂的计算,我们的程序大多时间花费在I/O读取上. 看到一个数据:IO操作可以比数据处理慢几个数量级.高端SSD固态硬盘的读取速度可以达到200mb-700mb/s;读取1000字节需要1.4微秒.而在此期间,2GHZ频率的CPU可以执行28000个指令处理周期.而网络数据的IO甚至更慢! NodeJS采用单线程非阻塞的架构解决老大难的IO问题 当采用多线程时,为每一个请求开启一个新的线程(Apac
-
javascript中的event loop事件循环详解
前言 javascript是单线程的语言,也就是说,同一个时间只能做一件事.而这个单线程的特性,与它的用途有关,作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM.这决定了它只能是单线程,否则会带来很复杂的同步问题.比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准? 为了利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是
-
JS事件循环机制event loop宏任务微任务原理解析
首先看一段代码 async function (){ await f2() console.log('f1') } async function f2(){ console.log('f2') } console.log('正常1') f1() setTimeout(()=>{ console.log('定时器') }) console.log('正常2') 正确的打印顺序应该是:正常1,f2 ,正常2,f1,定时器 为什么会出现这样打印顺序呢 首先javascript是一门单线程语言,在最新的
-
node.js事件循环机制及与js区别详解
目录 一.是什么 二.流程 三.题目 一.是什么 在浏览器事件循环(opens new window)中,我们了解到javascript在浏览器中的事件循环机制,其是根据HTML5定义的规范来实现 而在NodeJS中,事件循环是基于libuv实现,libuv是一个多平台的专注于异步IO的库,如下图最右侧所示: 上图EVENT_QUEUE 给人看起来只有一个队列,但EventLoop存在6个阶段,每个阶段都有对应的一个先进先出的回调队列 二.流程 上节讲到事件循环分成了六个阶段,对应如下: tim
-
实例分析js事件循环机制
本文通过实例给大家详细分析了JS中事件循环机制的原理和用法,以下是全部内容: var start = new Date() setTimeout(function () { var end = new Date console.log('Time elapsed:', end - start, 'ms') }, 500) while (new Date() - start < 1000) { } 有其他语言能完成预期的功能吗?Java, 在Java.util.Timer中,对于定时任务的解决方案
-
JavaScript事件循环及宏任务微任务原理解析
首先看一段代码: 打印顺序是什么? 正确答案:script start, script end, promise1, promise2, setTimeout 其中涉及到事件循环(event loop),宏任务(macrotask),微任务(microtask) 一.事件循环 Event Loop 程序中设置两个线程:一个负责程序本身的运行,称为"主线程":另一个负责主线程与其他进程(主要是各种I/O操作)的通信,被称为"Event Loop线程"(可以译为&quo
-
一文详解JS中的事件循环机制
目录 前言 1.JavaScript是单线程的 2.同步和异步 3.事件循环 前言 我们知道JavaScript 是单线程的编程语言,只能同一时间内做一件事,按顺序来处理事件,但是在遇到异步事件的时候,js线程并没有阻塞,还会继续执行,这又是为什么呢?本文来总结一下js 的事件循环机制. 1.JavaScript是单线程的 JavaScript 是一种单线程的编程语言,只有一个调用栈,决定了它在同一时间只能做一件事.在代码执行的时候,通过将不同函数的执行上下文压入执行栈中来保证代码的有序执行.在
-
JS事件循环-微任务-宏任务(原理讲解+面试题分析)
目录 前言 浏览器的事件循环 浏览器的事件循环 浏览器的宏任务.微任务 面试题一 面试题二 node的事件循环 node的事件循环 node的宏任务.微任务 面试题一 前言 JS代码在运行时,有两种运行环境. 一是在浏览器中,二是在node中. 由于JS线程是单线程,在运行JS代码时,可能会遇到比较耗时的操作,比如setTimeout,或者是发送网络请求等,又由于JS线程是单线程,如果在解析耗时的代码时候,停在了这里,那执行代码的性能将是比较低的. 为了解决此问题,在浏览器.node环境下,其实
-
实例详解JS中的事件循环机制
目录 一.前言 二.宏.微任务 三.Tick 执行顺序 四.案例详解 1.掺杂setTimeout 2.掺杂微任务,此处主要是Promise.then 3.掺杂async/await 一.前言 之前我们把react相关钩子函数大致介绍了一遍,这一系列完结之后我莫名感到空虚,不知道接下来应该更新有关哪方面的文章.最近想了想,打算先回归一遍JS基础,把一些比较重要的基础知识点回顾一下,然后继续撸框架(可能是源码.也可能补全下全家桶).不积跬步无以至千里,万丈高楼咱们先从JS的事件循环机制开始吧,废话
-
JavaScript 关于事件循环机制的刨析
目录 前言: 一.事件循环和任务队列产生的原因: 二.事件循环机制: 三.任务队列: 3.1 任务队列的类型: 3.2 两者区别: 3.3 更细致的事件循环过程 四.强大的异步专家 process.nextTick() 4.1 process.nextTick()在何时调用? 前言: 这次主要整理一下自己对 Js事件循环机制,同步,异步任务,宏任务,微任务的理解,大概率暂时还有些偏差或者错误.如果有,十分欢迎各位纠正我的错误! 一.事件循环和任务队列产生的原因: 首先,JS是单线程,这样设计也是
-
简单聊聊JavaScript的事件循环机制
目录 前言 概念 举个栗子 TIP 再次举个栗子 总结 前言 JavaScript是一门单线程的弱类型语言,但是我们在开发中,经常会遇到一些需要异步或者等待的处理操作. 类似ajax,亦或者ES6中新增的promise操作用于处理一些回调函数等. 概念 在JavaScript代码执行过程中,可以分为同步队列和异步队列. 同步任务类似我们常说的立即执行函数,不需要等待可以直接进行,可以直接进入到主线程中去执行,类似正常的函数调用等. 异步队列则是异步执行函数,类似ajax请求,我们在发起的过程中,
随机推荐
- Php做的端口嗅探器--可以指定网站和端口
- flex导出excel具体实现
- 体验MySQL5.6.25并处理所遇到的问题
- JavaScript Math.ceil 方法(对数值向上取整)
- js改变透明度实现轮播图的算法
- phpMyadmin 用户权限中英对照
- PHP实现对xml进行简单的增删改查(CRUD)操作示例
- scp命令详解(全)
- CSS整体布局声明的一些使用技巧
- 防止别人盗链的好方法推荐
- Windows系统下安装Mongodb 3.2.x的步骤详解
- Android 控件(button)对齐方法实现详解
- spring boot整合RabbitMQ(Direct模式)
- php readfile()修改文件上传大小设置
- 朋友圈实现图片+文字转发功能(必看篇)
- Django的分页器实例(paginator)
- Java NIO Path接口和Files类配合操作文件的实例
- Centos 6.5环境实现本地局域网搭建YUM的方法【基于HTTP】
- SpringBoot 整合Redis 数据库的方法
- 详解Python3中setuptools、Pip安装教程