JavaScript执行机制理解

js是一门单线程语言
单线程的原因之一就是js要操作Dom,如果是多线程,一边要修改节点,一边要删除节点,很容易造成混乱。
既然是单线程,那它所有的任务应该是同步执行的,可事实上js中有很多异步任务。比如回调函数,promise,setTimeout等。

单线程如何实现异步?
js必须运行在浏览器或node服务器中。js单线程指的是只有一个js引擎线程,而js运行环境(浏览器)是多进程的。
浏览器进程中(这里就不罗列了),最重要的就是渲染进程。
渲染进程:也就是浏览器内核,渲染引擎决定了浏览器如何显示网页的内容以及页面的格式信息。渲染进程是多线程的,下面罗列一下都有哪些线程。

  1. GUI渲染线程
  2. JS引擎线程
  3. 事件触发线程
  4. 定时器触发线程
  5. 异步HTTP请求线程

js实现能实现异步与这些线程息息相关。其中js引擎线程也就是js内核,由他负责解析js代码,运行脚本。
说说异步,假如现在正在执行一段同步任务,遇到了一个异步任务,就比如ajax请求。当遇到ajax请求时,js引擎会给这个ajax请求注册一个回调函数,然后这个ajax请求就会放到异步HTTP请求线程上去处理,js引擎继续执行同步任务,当这个ajax请求有了结果,浏览器就会将这个注册的回调函数添加到任务队列,等到执行栈为空时,js主线程(js引擎)就会将任务队列里的回调函数调入主线程来执行。
这么来看,js单线程是只有一个主线程,其他线程会辅佐这个主线程执行一些异步任务,当异步任务执行完,还是需要把任务(通过回调函数的形式)放到事件队列中等待主线程来执行。

为什么需要回调函数呢?
一个异步任务如果没有回调函数,那就无法进入任务队列,那么这个异步任务也就不能被主线程调用。

事件循环
到这里,可以看看js的执行机制。js执行机制就是事件循环
偷来的图
当一个任务进入执行栈之前,js引擎会先判断该任务是同步任务还是异步任务。同步任务会进入执行栈,异步任务会先注册一个回调函数,然后被挂起,等到异步任务有了结果后,浏览器会将这个异步任务加入到任务队列(Event Queue)中,等到执行栈中的同步任务全部执行完,主线程会去任务队列中查看是否有等待被调用的异步任务,若有,就将一个异步任务调入主线程来执行,js引擎会循环检查事件队列,并将他们调入主线程,直到任务队列为空。这样循环向任务队列添加事件,调入主线程执行事件就称作事件循环。
除了广义的同步任务,异步任务。还有微任务和宏任务的定义。
宏任务:js代码,setTimeout,setInterval
微任务:promise,process.nextTick
不同类型的任务会进入不同的Event Queue宏任务会进入宏任务队列,微任务会进入微任务队列。
js引擎首先会执行js代码,js代码作为宏任务进入主线程,执行过程中遇到微任务添加到微任务队列,遇到宏任务添加到宏任务队列,在当前宏任务执行完之后,会执行微任务队列所有的微任务,然后从宏任务队列中取出一个宏任务开始执行,继续循环上述过程。
注:遇到promise,promise里的代码立即执行,当resolve或reject被调用时会将then方法添加到微任务队列中。

参考文章:
javaScript执行机制
同步任务和异步任务
从浏览器多进程到JS单线程,JS运行机制最全面的一次梳理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值