JavaScript执行模型怎么理解,有哪些重点知识
Admin 2022-05-20 群英技术资讯 415 次浏览
JavaScript执行模型
引言
JavaScript是一个单线程(Single-threaded)异步(Asynchronous)非阻塞(Non-blocking)并发(Concurrent)语言,这些语言效果通过一个调用栈(Call Stack)、一个事件循环(Event Loop)、一个回调队列(Callback Queue)有些时候也叫任务队列(Task Queue)与跟运行环境相关的API组成。
概念
调用栈 Call Stack
调用栈是一个LIFO后进先出数据结构的函数运行栈,它内部的数据结构为函数帧。当在JavaScript中调用一个函数时,它将被压入栈中,当这个函数内部还有另一个函数被调用时,另一个函数将会被压入栈顶,直到其内部没有更多调用,栈顶函数将会被以单线程方式执行并出栈,直到最后一个函数帧出栈。JavaScript语言特性中的单线程就是指的调用栈的单线程运行。
function multiply(a, b) { return a * b; } function square(n) { return multiply(n, n) } function printSquare(n) { console.log(square(n)); } printSquare(4);
首先调用栈压入main()
,扫描到printSquare()
函数调用调用栈压入printSquare(4)
,printSquare
函数内部调用square(n)
该函数被压入栈,同理multiply(n, n)
函数也被压入栈且没有更多调用,JavaScript引擎开始执行栈顶函数multiply(n, n)
返回结果并出栈,以此类推直到main()函数出栈。
调用栈有一个意外情况,当函数递归调用其自身时调用栈将溢出,执行环境将报错。
function foo() { foo(); } foo();
任务队列 Task Queue
任务队列是WebAPI的一部分,也就是说它本身并不是ECMAScript标准的一部分,而是运行环境自行实现的。任务队列是所有回调函数排队执行的FIFO先进先出队列,它的单位是任务(Task),每个任务都关联着一个用于处理这个任务的回调函数。在事件循环(Event Loop)中会将任务队列内的函数压入调用栈执行并出队列,直至为空。
任务队列在浏览器的实现中被分为了宏任务队列(macrotask queue)和微任务队列(microtask queue),它们分别个自承载宏任务(macrotask)和微任务(microtask)的排队,其中宏任务队列与宏任务又被默认为常规的任务队列与任务。
当调用栈内所有调用都完成执行后,事件轮询会在每次处理宏任务队列的一个宏任务后处理微任务队列的全部微任务,也就是微任务基本会在宏任务处理之前被处理。微任务处理中间不会被UI或网络事件处理被执行,微任务执行是连续的。
会被添加到宏任务的方法的回调有:
会被添加到微任务的Web API方法有:
会被添加到微任务的Web API方法有:
微任务只会从我们编写的代码中产生,宏任务既可能从我们编写的代码中产生也可能从浏览器本身事件、渲染、IO产生。
事件循环 Event Loop
事件循环是JavaScript的事件处理机制,它会一直轮询消息队列,当满足调用栈为空且消息队列不为空时,它将把消息队列队头的消息压入执行栈。这样的机制保证了函数不会被中断,不会有线程切换带来的数据不一致等情况
事件循环在调用栈为空时轮询,顺序为
1.找到任务队列(宏任务队列)的最早被添加的任务并将其添加到调用栈执行
2.执行所有微任务队列内的任务
3.渲染所有变化
4.如果宏任务队列为空等待宏任务出现
5.返回步骤1
JavaScript运行时 Runtime
浏览器的JavaScript代码执行也就是调用栈与堆(用于储存变量对象等)由JavaScript引擎提供,用的比较多的是谷歌的V8引擎,Chrome、Edge浏览器、Nodejs均使用该引擎。
事件循环Event Loop、任务队列Task Queue(回调队列Callback Queue)、WebAPI或Node API由运行环境提供。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
本文我们来来接怎样实现更容易扩展的JavaScript进度管理方式,下文有很详细的原理介绍及测试,对大家学习和工作都有一定的参考价值,感兴趣的朋友就继续往下看吧。
node.js显示乱码的解决办法:1、通过记事本查看nodeJs的编码格式,并设置编码格式为utf-8;2、在js文件中增加编码说明即可。
这篇文章主要介绍了uni-app 的模板语法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
生成器有throw方法,该方法与next的效果相同。唯一的区别是next方法传输的参数回到正常值。throw方法传输的参数是错误的对象。
这篇文章主要给大家分享的是JavaScript 的反射学习技巧,主要是区别在于所有的函数对象属性过于复杂,而且额外增加可能会导致程序行为不合理,所以扩展 Reflect 函数来专门对函数对象处理调用方法,构造对象,获取或者设置属性等相关操作。下面一起进入文章内容吧
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008