JS事件循环机制(event loop)

一、JS单线程、异步、同步概念

  众所周知,JS是单线程(如果一个线程删DOM,一个线程增DOM,浏览器傻逼了~所以只能单着了),虽然有webworker酱紫的多线程出现,但也是在主线程的控制下。webworker仅仅能进行计算任务,不能操作DOM,所以本质上还是单线程。

  单线程即任务是串行的,后一个任务需要等待前一个任务的执行,这就可能出现长时间的等待。但由于类似ajax网络请求、setTimeout时间延迟、DOM事件的用户交互等,这些任务并不消耗 CPU,是一种空等,资源浪费,因此出现了异步。通过将任务交给相应的异步模块去处理,主线程的效率大大提升,可以并行的去处理其他的操作。当异步处理完成,主线程空闲时,主线程读取相应的callback,进行后续的操作,最大程度的利用CPU。此时出现了同步执行和异步执行的概念,同步执行是主线程按照顺序,串行执行任务;异步执行就是cpu跳过等待,先处理后续的任务(CPU与网络模块、timer等并行进行任务)。由此产生了任务队列与事件循环,来协调主线程与异步模块之间的工作。

二、事件循环机制

                        事件循环示例图

 

  如上图为事件循环示例图(或JS运行机制图),流程如下:

    step1:主线程读取JS代码,此时为同步环境,形成相应的堆和执行栈;

    step2:  主线程遇到异步任务,指给对应的异步进程进行处理(WEB API);

    step3:  异步进程处理完毕(Ajax返回、DOM事件处罚、Timer到等),将相应的异步任务推入任务队列;

    step4: 主线程执行完毕,查询任务队列,如果存在任务,则取出一个任务推入主线程处理(先进先出);

    step5: 重复执行step2、3、4;称为事件循环。

  执行的大意:

    同步环境执行(step1) -> 事件循环1(step4) -> 事件循环2(step4的重复)…

  其中的异步进程有:

    a、类似onclick等,由浏览器内核的DOM binding模块处理,事件触发时,回调函数添加到任务队列中;

    b、setTimeout等,由浏览器内核的Timer模块处理,时间到达时,回调函数添加到任务队列中;

    c、Ajax,由浏览器内核的Network模块处理,网络请求返回后,添加到任务队列中。

三、任务队列

  如上示意图,任务队列存在多个,同一任务队列内,按队列顺序被主线程取走;不同任务队列之间,存在着优先级,优先级高的优先获取(如用户I/O);

  3.1、任务队列的类型

    任务队列存在两种类型,一种为microtask queue(微任务队列),另一种为macrotask queue(宏任务队列)

    图中所列出的任务队列均为macrotask queue,而ES6 的 promise.then产生的任务队列为microtask queue。

  3.2、两者的区别

    microtask queue:唯一,整个事件循环当中,仅存在一个;执行为同步,同一个事件循环中的microtask会按队列顺序,串行执行完毕;

    macrotask queue:不唯一,存在一定的优先级(用户I/O部分优先级更高);异步执行,同一事件循环中,只执行一个。

  3.3、更完整的事件循环流程    

    将microtask加入到JS运行机制流程中,则:

      step1、2、3同上,

      step4:主线程查询任务队列,执行microtask queue,将其按序执行,全部执行完毕;

      step5:主线程查询任务队列,执行macrotask queue,取队首任务执行,执行完毕;

      step6:重复step4、step5。

    microtask queue中的所有callback处在同一个事件循环中,而macrotask queue中的callback有自己的事件循环。

    简而言之:同步环境执行 -> 事件循环1(microtask queue的All)-> 事件循环2(macrotask queue中的一个) -> 事件循环1(microtask queue的All)-> 事件循环2(macrotask queue中的一个)...

    利用microtask queue可以形成一个同步执行的环境,但如果Microtask queue太长,将导致Macrotask任务长时间执行不了,最终导致用户I/O无响应等,所以使用需慎重。

 

四、示例、验证  

复制代码

            console.log('1, time = ' + new Date().toString())
            setTimeout(macroCallback, 0);
            new Promise(function(resolve, reject) {
                console.log('2, time = ' + new Date().toString())
                resolve();
                console.log('3, time = ' + new Date().toString())
            }).then(microCallback);

            function macroCallback() {
                console.log('4, time = ' + new Date().toString())
            } 

            function microCallback() {
                console.log('5, time = ' + new Date().toString())
            }     

复制代码

  结合第二节与第三节的分析,此处的执行流程应为:

    同步环境:1 -> 2 -> 3

    事件循环1(microCallback):5

    事件循环2(macroCallback):4

  运行结果如下:

    

  运行结果与预期一致,验证了在不同类型的任务队列中,microtask queue中的callball将优先执行。

    总结:由此我们了解事件循环的机制,同时了解了任务队列、JS主线程、异步操作之间的相互协作;同时认识了两种任务队列:macrotask queue、microtask queue,它们由不同的标准制定,microtask queue对应ECMAScript的promise属性(ES6)和 DOM3的MutationObserver,文中说明了两者在事件循环中的运行情况及区别;在今后的异步操作中,通过灵活运用不同的任务队列,提升用户交互性能,给出更加的响应和视觉体验;同时,通过JS的事件循环机制,可以更清楚JS代码的执行流,从而更好的控制代码,更有效、更好的为业务服务。 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值