JavaScript的执行机制
JavaScript是单线程的,任务的执行时自上而下的,这就有了一个问题,当遇到一个比较耗时的任务时,下面的代码就会被阻塞,这就意味着卡死。所以js是有异步的,它的实现主要是通过事件循环(event loop)
事件循环
JavaScript中的任务分为两种:同步和异步
按照分类,当有任务执行时:
- 判断是同步还是异步,同步进入主线程,异步进入event table
- 异步任务在event table中注册函数,当满足触发条件,推入event queue
- 同步任务进入主线程后一直执行,直到主线程空闲时,才会到event queue中查看是否有可执行的异步任务,如果有就推入到主线程中执行
以上三步循环执行,就是event loop
看这幅图

如:
console.log("1")
setTimeout(function() {
console.log(2)
}, 1000)
console.log(3)
- consloe.log(1),同步任务,进入主线程
- setTimeout(),异步任务,进入event table,1秒后进入event queue里
- console.log(3),同步任务,放入主线程
- 先执行主线程中的任务,此时,主线程有,打印1,打印3
- 当主线程执行结束,主线程空闲,于是,主线程到event queue(事件队列)里查看是否有可执行的函数,于是打印2
宏任务和微任务
除了之前说过的同步任务和异步任务,还有更精细的定义:
- macro-task(宏任务):包含整体代码script,setTimeout,setlnterval
- micro-task(微任务):Promise,process.nextTick
不同的任务会进入不同的event queue,比如setTimeout,setlnterval会进入相同的event queue,Promise,process.nextTick会进入相同的event queue
事件循环的顺序,决定js代码的执行顺序,进入整体代码(宏任务)后,开始第一次循环。接着执行所有微任务。然后再从宏任务开始,待一个任务队列执行完毕,再执行微任务。代码演示
console.log("start")
setTimeout(function(){
console.log("setTimeout")
},0)
new Promise(function(resolve){
resolve()
console.log("promise")
}).then(function(){
console.log("then")
})
console.log("end")
先按照最开始的方式解释,及同步任务和异步任务
- console.log("start"),同步任务,进入主线程,直接打印
- setTimeout,异步任务,进入event table
- Promise,同步任务,进入主线程,直接打印
- then,异步,放入event table
- console.log("end")同步任务,直接打印
- 结束,先执行主线程的任务,start => promise => end ,主线程结束,查看任务队列中是否有待执行的任务,打印 setTimeout => then
- 即,start => promisr => end => setTimeout => then
然而执行的结果却是这样的:start => promisr => end => then => setTimeout
所以我们要同过宏任务和微任务的方式解释
- 首先执行script下的宏任务,遇到console.log("start"),直接打印 “start”
- 遇到setTimeout,将其放入宏任务队列
- 遇到promise,直接执行,打印 “promise”
- 遇到then,微任务,放入微任务队列
- 遇到console.log("end"),直接打印 “end”
- 此时,整体script作为第一个宏任务执行结束,看看有没有微任务,发现有个then在微任务的event queue中,执行,打印“then”
- 到此第一轮事件循环结束,开始第二轮事件循环,当然要从宏任务event queue开始,此时宏任务event queue中有setTimeout,立即执行,打印“setTimeout”
- 结束,此时的顺序start => promisr => end => then => setTimeout
来看关系图

最后
要知道js是一门单线程语言,所有实现异步的方式,其实都是用同步模拟出来的,而事件循环event loop 是实现异步的一种方法,也是js的执行机制
JavaScript的执行机制的更多相关文章
- javaScript的执行机制-同步任务-异步任务-微任务-宏任务
一.概念理解 1.关于javascript javascript是一门单线程语言,在最新的HTML5中提出了Web-Worker,但javascript是单线程这一核心仍未改变.所以一切javascr ...
- javascript的执行机制—Event Loop
既然今天要谈的是javascript的事件循环机制,要理解事件循环,首先要知道事件循环是什么. 我们先从一个例子来看一下javascript的执行顺序. <script> setTimeo ...
- 一段代码说明javascript闭包执行机制
假设你能理解以下代码的执行结果,应该就算理解闭包的执行机制了. var name = "tom"; var myobj = { name: "jackson", ...
- JavaScript 的执行机制
一.关于javascript javascript是一门单线程语言,在最新的HTML5中提出了Web Worker,但javascript是单线程这一核心仍未改变. 为什么js是单线程的语言?因为最初 ...
- javascript执行机制
文的目的就是要保证你彻底弄懂javascript的执行机制,如果读完本文还不懂,可以揍我. 不论你是javascript新手还是老鸟,不论是面试求职,还是日常开发工作,我们经常会遇到这样的情况:给定的 ...
- 彻底弄懂 JavaScript 执行机制
本文的目的就是要保证你彻底弄懂javascript的执行机制,如果读完本文还不懂,可以揍我. 不论你是javascript新手还是老鸟,不论是面试求职,还是日常开发工作,我们经常会遇到这样的情况:给定 ...
- JavaScript 执行机制
一.宏任务与微任务 macro-task(宏任务):包括整体代码script,setTimeout,setInterval micro-task(微任务):Promise,process.nextTi ...
- 转载---JavaScript执行机制
很好的一篇文章,原地址 JavaScript执行机制 这一次,彻底弄懂 JavaScript 执行机制 本文的目的就是要保证你彻底弄懂javascript的执行机制,如果读完本文还不懂,可以揍我. 不 ...
- 【js】javaScript 执行机制
javascript 是一门单线程语言(按照语句一行一行的执行) let a = '1'; console.log(a); let b = '2'; console.log(b); 这样子正常执行是没 ...
随机推荐
- Flume启动错误之:Bootstrap Servers must be specified
今天测试项目的时候需要启动Flume,然而在启动时遇到了Bootstrap Servers must be specified错误,错误日志如下: [kfk@bigdata-pro01 flume-- ...
- 执行ORACLE SQL时如何 忽略替换变量(转载)
你想在SQL*Plus里执行一个脚本,脚本里包含了一些看起来像替换变量的元素,但实际上你并不是想把它们当替换变量来处理.这时你想让解析器忽略它们而不是提示用户输入.解决方案1有一种解决方案就是在&am ...
- pat04-树9. Path in a Heap (25)
04-树9. Path in a Heap (25) 时间限制 150 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue Insert ...
- 【snmp】测试流程
一.SNMP协议概述 SNMP是基于TCP/IP协议族的网络管理标准,是一种在IP网络中管理网络节点(如服务器.工作站.路由器.交换机等)的标准协议.SNMP能够使网络管理员提高网络管理效能,及时发现 ...
- centos6.3 配置防火墙,开启80端口、3306端口
vi /etc/sysconfig/iptables -A INPUT -m state –state NEW -m tcp -p tcp –dport 80 -j ACCEPT(允许80端口通过防火 ...
- 基于HTTP协议之WEB消息实时推送技术原理及实现
很早就想写一些关于网页消息实时推送技术方面的文章,但是由于最近实在忙,没有时间去写文章.本文主要讲解基于 HTTP1.1 协议的 WEB 推送的技术原理及实现.本人曾经在工作的时候也有做过一些用到网页 ...
- 设计模式之工厂模式详细读后感TT!(五)
一如既往:原文 工厂方法(factory method)模式的意义是定义一个创建产品对象的工厂接口, 将实际创建工作推迟到子类当中. 核心工厂的创建, 这样核心类成为一个抽象工厂角色, 仅仅复制工厂子 ...
- form提交
方法一:利用form的onsubmit()函数(经常使用) <script type="text/javascript"> function validateForm( ...
- ASP.NET MVC 音乐商店 - 2.控制器
在典型的 Web 应用中,用户请求的 URL 地址通常映射到保存在网站中的文件上,例如,当用户请求 /Products.aspx 的时候,或者 /Products.php 的时候,很可能是在通过处理 ...
- c语言 Implement strStr()【Leetcode】
实现在一个母字符串中找到第一个子字符串的位置. #include <stdio.h> #include <string.h> #define _IRON_TRUE 1 #def ...