函数调用栈、任务队列、事件轮询、宏任务、微任务

摘要:
输出结果为“1”、“2”、“set2”和“setTimeout”步骤1:setTimeout是一个异步任务,回调函数被添加到任务队列中,主进程首先执行后续任务。

函数调用栈:(call stack)

  index.js

  函数调用栈、任务队列、事件轮询、宏任务、微任务第1张

特点:先入栈,先执行。(从上往下执行,就代码的执行顺序)执行前入栈,执行后出栈。a先执行完 a先出栈,后续就是B出栈,接着就是整个全局上下文出栈,成为空栈。

任务队列:(task queue)

队列特点: 先进先出。 

在单线程的js中,任务分为同步任务和异步任务。

同步任务:在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务。

异步任务:同样在主线程执行,只是将异步任务加入到任务队列中或者事件队列中,等主线程的同步任务执行完毕,就执行任务队列中的事件,事件对应的事件处理函数,加入前面所讲的函数执行栈执行。

函数调用栈、任务队列、事件轮询、宏任务、微任务第2张

 输出结果是 "1" "2" "set2" "setTimeout"

第一步: setTimeout 是个异步任务,回调函数加入任务队列,主线程先执行后续的任务。

第二步:for循环同步任务,  console.log("1") 先进栈,后出栈。

第三步: setTimeout 跟第一步处理一致。

第四步: for循环同步任务 console.log("2") 先进战。后出栈。

第五步: 栈任务完成之后,会不断轮询,任务队列中的回调函数,回调函数重新进入主线程的调用栈,输出数据,完成出栈。

事件轮询(Event Loop): 只要异步任务中的等待时间结束后,触发事件处理函数,该函数就会被推入函数执行栈。不断重复这个过程,就是事件轮询。

setTimeout: 表明的是等待多少毫秒后,将事件处理程序推入到函数执行栈,并不是等待多少毫秒后立马执行该事件处理程序,什么时候执行,要取决于当前主进程有没有相关任务在执行,如果前面没有相关任务,就会读取该任务执行。

函数调用栈、任务队列、事件轮询、宏任务、微任务第3张

宏任务与微任务:

宏任务:  主进程代码、setTimeout里的回调、setInterval回调

微任务: promise.then catch finally 等

函数调用栈、任务队列、事件轮询、宏任务、微任务第4张

执行顺序: 主进程宏任务(主进程代码) ---> 主进程微任务(promise.then) ---> 异步队列里的宏任务(定时器回调)

实例:  输出: 外层宏事件1 外层宏事件2  微事件1 微事件2 内层宏事件3

setTimeout(() => {
    //执行后 回调一个宏事件
    console.log('内层宏事件3')
}, 0)
console.log('外层宏事件1');

new Promise((resolve) => {
    console.log('外层宏事件2');
    resolve()
}).then(() => {
    console.log('微事件1');
}).then(()=>{
    console.log('微事件2')
})

免责声明:文章转载自《函数调用栈、任务队列、事件轮询、宏任务、微任务》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇[转]C#通过委托更新UI(异步加载)WordPress插件制作教程(三): 添加菜单的方法下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

转载:堆栈溢出(Stack overflow)问题

一,堆栈溢出堆栈溢出就是不顾堆栈中分配的局部数据块大小(在栈中分配的局部数据块大小和局部变量的声明的大小有关),向该数据块写入了过多的数据,导致数据越界,结果覆盖了老的堆栈数据(包括函数的返回地址)。 或者解释为在长字符串中嵌入一段代码,并将过程的返回地址覆盖为这段代码的地址,这样当过程返回时,程序就转而开始执行这段自编的代码了.这东西很像病毒。 基础知识...

深度分析WM_PAINT和WM_ERASEBKGND消息

       做windows开发这么久了,一直以来对WM_PAINT和WM_ERASEBKGND消息总是感觉理解的不准确,每次要自绘一个窗口都因为知其然不知其所以然,偶然发现一篇文章,详细透彻地分了这个两个消息的用途和设计初衷,这篇文章也是我见过最深入也是最准确关于WM_PAINT和WM_ERASEBKGND消息的,文中每一句话都值得咀嚼。先转载如下:...

【STM32H7】第6章 ThreadX操作系统移植(IAR)

论坛原始地址(持续更新):http://www.armbbs.cn/forum.php?mod=viewthread&tid=99514 第6章   ThreadX操作系统移植(IAR) 本章节将为大家介绍ThreadX内核的IAR方式移植和设计框架,理论上不建议初学者直接学习,因为本章节涉及到的知识点很多,建议对ThreadX的应用有一些了解后再...

安卓进阶:元注解Support Annotation Library使用详解

Support Annotation Library是一个函数包,包含一系列有用的元注解。 注解目录:  Nullness注解  资源类型注解 类型定义注解 线程注解 RGB颜色值注解 值范围注解 权限注解 重写函数注解 返回值注解 @VisibleForTesting @Keep 实用主义至上,不记录历史和版本这些,现在直接了解一下这个函数包有什么用...

linux c 用户态调试追踪函数调用堆栈以及定位段错误[转载]

一般察看函数运行时堆栈的方法是使用GDB(bt命令)之类的外部调试器,但是,有些时候为了分析程序的BUG,(主要针对长时间运行程序的分析),在程序出错时打印出函数的调用堆栈是非常有用的。 在glibc头文件"execinfo.h"中声明了三个函数用于获取当前线程的函数调用堆栈。 int backtrace(void **buffer,int size) 该...

【DLL相关】实现函数的DLL封装,并在另一个项目中调用

直接给出步骤: ===========函数的DLL封装=========== 1.创建第一个项目:win32控制台程序,应用程序类型:DLL,附加选项:导出符号(命名:double_dll) 2.double_dll.h中加入函数定义   extern DOUBLE_DLL_API int doublefun(int);//DOUBLE_DLL_API 根...