我不知道的javascript异步机制

js是单线程的

单线程说明在某个特定时刻只有特定的代码能够被执行,并阻塞其他的代码。JavaScript 代码的执行是单线程的(同一时刻内只会有一段代码在执行)

 

js的中的同步和异步

既然JS是单线程,那就像只有一个窗口的银行,客户需要排队一个一个办理业务,同理JS任务也要一个一个顺序执行。如果一个任务耗时过长,那么后一个任务也必须等着。那么问题来了,假如我们想浏览新闻,但是新闻包含的超清图片加载很慢,难道我们的网页要一直卡着直到图片完全显示出来?因此Javascript语言将任务的执行模式分成两种:

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

异步任务(asynchronous):每个任务分成2段,第一段代码包含对外部数据的请求,第二段代码被写成一个回调函数,包含了对外部数据的处理,第一段执行完毕不是立即执行第二段代码,而是将程序的执行权交给第二个任务,等到外部数据返回了,再由系统通知执行第二段代码,程序的执行顺序与任务的排列顺序是不一致的,不进入主线程,而进入"任务队列"(task queue),只有任务队列通知主线程,某个异步任务可以执行了,该任务才会进入主线程。js中的异步事件有:

  • AJax请求
  • 定时器
  • 事件
  • 回调函数

 

事件循环(Event Loop)

同步和异步任务分别进入不同的执行“场所”,同步的进入主线程,异步的进入Event Table并注册函数。

当指定的事情完成时,Event Table会将这个函数移入Event Queue。

主线程内的任务执行完毕为空(JS引擎中存在monitoring process进程,它会持续不断的检查主线程执行栈是否为空,一旦为空,就会去Event Queue那里检查是否有等待被调用的函数),会去Event Queue读取对应的函数,进入主线程执行。

上述过程会不断重复,也就是常说的Event Loop(事件循环)

 

浏览器是多线程的

虽然JavaScript是单线程的,可是浏览器内部不是单线程的。一些I/O操作、定时器的计时和事件监听(click, keydown...)等都是由浏览器提供的其他线程来完成的,一个浏览器通常由一下几个常住的线程:

  • 渲染引擎线程:顾名思义,该线程负责页面的渲染
  • js引擎线程:负责js解析和执行
  • 定时触发器线程:处理定时事件,比如setTimeout,setInterval
  • 事件触发线程:处理DOM事件
  • 异步http请求线程:处理http请求

渲染线程和js引擎线程是不能同时进行的。渲染线程在执行任务的时候,js引擎线程会被挂起因为js可以操作DOM,若在渲染中js处理了DOM,浏览器可能就不知所措了。这种机制有什么用呢?

JavaScript为了简化编程的复杂度,不支持对线程的直接操作,而在底层, JavaScript 的异步机制其实是浏览器的两个或以上常驻线程共同完成的,例如异步请求是由两个常驻线程:

JavaScript 引擎线程 和 事件触发线程 共同完成的,JavaScript 的执行线程执行代码,发起异步请求。这时浏览器会开一条 新的 HTTP 请求线程 来执行异步请求,这时 JavaScript 执行

线程的任务已完成,继续执行 JavaScript 执行线程队列中剩下的其他代码(或叫做任务)。然后在未来的某一时刻 事件触发线程 监视到之前的发起的 HTTP 请求已完成,它就会把事件

完成的回调函数(注入必要的事件结果参数)插入到 JS 执行队列的尾部等待 JS 处理。

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_21439711

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值