热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

关于javascript的eventloop如何理解eventqueue的优先级?

最近看了javascript的eventloop相关资料,对eventqueue队列优先级没有理解到位还请各位大神帮我指点一二。第一篇是阮一峰老师的JavaScript运行机制详解:

最近看了Javascript的eventloop相关资料,对event queue队列优先级没有理解到位还请各位大神帮我指点一二。
第一篇是阮一峰老师的Javascript 运行机制详解:再谈Event Loop;这里面有讲到eventloop循环机制,其中有一个event queue队列,里面存放着异步任务的callback;在执行栈执行完成时就会从队列中读取队列任务并执行。这里并没有涉及到优先级,只介绍了event queue是FIFO数据结构。
然后看了第二篇波同学的前端基础进阶(十二):深入核心,详解事件循环机制
波同学在里面讲到了队列分为宏任务和微任务,而且微任务会在执行栈执行完后立即执行,而宏任务要等到下一次的event loop才会被执行;



这里有一个疑问就是eventloop循环机制中到底是只有一个queue队列还是有宏队列和微队列?因为他们俩讲的不同

不管是微任务队列还是宏任务队列都是遵循FIFO,那队列中的任务被读取到执行栈时也应该是按照这个顺序来执行,那该如何理解队列中任务的优先级?比如dom事件操作,ajax请求的回调、以及setTimeout他们之间是否有优先级?



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
console.log('start');

var xhr = new XMLHttpRequest();

var url = 'test.json';

xhr.open('GET', url,true);

xhr.Onreadystatechange= function() {

    if (xhr.status == 200 && xhr.readyState == 4) {

        console.log(xhr.responseText)

    }

}

xhr.send();

setTimeout(function() {

    console.log('timeout')

}, 0)

for (var i = 0; i <3000000000; i++) {}



var btn = document.querySelector("#btn");

btn.Onclick= function() {

    console.log('click')

}



new Promise((reslove, reject) => {

    console.log('promise');

    reslove();

}).then((res) => {

    console.log('promise finish')

})

console.log('end');

输出结果:

1
2
3
4
5
6
7
8
9
start

 promise

 end

 promise finish

 click

 {

    "test":"aa"

 }

 timeout

这里和我预期的有点不一样,我以为应该是ajax的回调先被执行到的,因为我故意停留了2-3秒来点击那个按钮,按理说ajax率先返回了应该被先加入到队列中,结果是click先先输出。。。这里是不是有优先级的存在?

------------------------------------------这是分割线2017-04-07更新---------------------------

经过一番折腾后,查看了很多大佬在这方面的博客文章在这里大概总结一些event loop的认识:

  1. 首先要明白的是event loop是由Javascript宿主环境(像浏览器)来实现的,js引擎他不关心也不知道event
    loop机制的运行和存在,他只负责从事件队列里面读取事件来执行,他不会也不会知道怎样向事件队列中push事件任务,这些都由宿主来完成。理解这第一点很重要要先知道是谁在做这件事情。


  2. 第二点就是一个宿主环境 只能有一个事件循环(Event loop),而一个事件循环可以多个任务队列(Task queue),每个任务都有一个任务源(Task source)。相同任务源的任务,只能放到一个任务队列中。不同任务源的任务,可以放到不同任务队列中。然后js引擎做的事就是不断的去读取这些队列里面的任务来执行,


  3. 任务可分为宏任务和微任务;他们的执行过程和顺序上面给的链接的波同学已经讲的很清楚明朗了。我再大概复述一遍:js引擎逐句的执行script整体代码,当遇到异步任务时,js的运行环境就会在适时的时候将这些事件任务push到相应的队列中去,等待着被js引擎去执行,而如果异步没有产生回调(callback)或者说是事件任务,那他就不会push到队列里面去,当js执行栈执行完成后,然后他把微任务队列中的任务读取过,并进行执行,在这执行过程中如果有产生新的异步任务也会按照上述的方式进行处理,当微任务执行完成后他会去读取宏任务队列中的任务并执行,然后周而复始的反复执行,直到把队列中的任务全部执行完。
    macro-task(宏任务): script(整体代码), setTimeout, setInterval, setImmediate, I/O, UI rendering;micro-task(微任务): process.nextTick, Promises(这里指浏览器实现的原生 Promise),Object.observe, MutationObserver


  4. 至于队列中的优先级,有一个大概的顺序process.nextTick > promise.then > setTimeout > setImmediate;优先级执行顺序可能还会和具体的宿主环境有关;边城大神也说的对对于异步我们更不应该去依赖他们的执行顺序既然是异步就当作无序的来处理。


参考资料:
1.Promise的队列与setTimeout的队列有何关联?
2.www.w3.org
3.http://stackoverflow.com/ques...
4.https://github.com/youngwind/...


   



推荐阅读
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • 本文讨论了如何在codeigniter中识别来自angularjs的请求,并提供了两种方法的代码示例。作者尝试了$this->input->is_ajax_request()和自定义函数is_ajax(),但都没有成功。最后,作者展示了一个ajax请求的示例代码。 ... [详细]
  • 网络请求模块选择——axios框架的基本使用和封装
    本文介绍了选择网络请求模块axios的原因,以及axios框架的基本使用和封装方法。包括发送并发请求的演示,全局配置的设置,创建axios实例的方法,拦截器的使用,以及如何封装和请求响应劫持等内容。 ... [详细]
  • React基础篇一 - JSX语法扩展与使用
    本文介绍了React基础篇一中的JSX语法扩展与使用。JSX是一种JavaScript的语法扩展,用于描述React中的用户界面。文章详细介绍了在JSX中使用表达式的方法,并给出了一个示例代码。最后,提到了JSX在编译后会被转化为普通的JavaScript对象。 ... [详细]
  • 一、什么是闭包?有什么作用什么是闭包闭包是定义在一个函数内部的函数,它可以访问父级函数的内部变量。当一个闭包被创建时,会关联一个作用域—— ... [详细]
  • express工程中的json调用方法
    本文介绍了在express工程中如何调用json数据,包括建立app.js文件、创建数据接口以及获取全部数据和typeid为1的数据的方法。 ... [详细]
  • Servlet多用户登录时HttpSession会话信息覆盖问题的解决方案
    本文讨论了在Servlet多用户登录时可能出现的HttpSession会话信息覆盖问题,并提供了解决方案。通过分析JSESSIONID的作用机制和编码方式,我们可以得出每个HttpSession对象都是通过客户端发送的唯一JSESSIONID来识别的,因此无需担心会话信息被覆盖的问题。需要注意的是,本文讨论的是多个客户端级别上的多用户登录,而非同一个浏览器级别上的多用户登录。 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 本文介绍了使用AJAX的POST请求实现数据修改功能的方法。通过ajax-post技术,可以实现在输入某个id后,通过ajax技术调用post.jsp修改具有该id记录的姓名的值。文章还提到了AJAX的概念和作用,以及使用async参数和open()方法的注意事项。同时强调了不推荐使用async=false的情况,并解释了JavaScript等待服务器响应的机制。 ... [详细]
  • 本文介绍了django中视图函数的使用方法,包括如何接收Web请求并返回Web响应,以及如何处理GET请求和POST请求。同时还介绍了urls.py和views.py文件的配置方式。 ... [详细]
  • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
  • 如何提高PHP编程技能及推荐高级教程
    本文介绍了如何提高PHP编程技能的方法,推荐了一些高级教程。学习任何一种编程语言都需要长期的坚持和不懈的努力,本文提醒读者要有足够的耐心和时间投入。通过实践操作学习,可以更好地理解和掌握PHP语言的特异性,特别是单引号和双引号的用法。同时,本文也指出了只走马观花看整体而不深入学习的学习方式无法真正掌握这门语言,建议读者要从整体来考虑局部,培养大局观。最后,本文提醒读者完成一个像模像样的网站需要付出更多的努力和实践。 ... [详细]
  • 本文介绍了如何使用JSONObiect和Gson相关方法实现json数据与kotlin对象的相互转换。首先解释了JSON的概念和数据格式,然后详细介绍了相关API,包括JSONObject和Gson的使用方法。接着讲解了如何将json格式的字符串转换为kotlin对象或List,以及如何将kotlin对象转换为json字符串。最后提到了使用Map封装json对象的特殊情况。文章还对JSON和XML进行了比较,指出了JSON的优势和缺点。 ... [详细]
  • Android实战——jsoup实现网络爬虫,糗事百科项目的起步
    本文介绍了Android实战中使用jsoup实现网络爬虫的方法,以糗事百科项目为例。对于初学者来说,数据源的缺乏是做项目的最大烦恼之一。本文讲述了如何使用网络爬虫获取数据,并以糗事百科作为练手项目。同时,提到了使用jsoup需要结合前端基础知识,以及如果学过JS的话可以更轻松地使用该框架。 ... [详细]
  • Hibernate延迟加载深入分析-集合属性的延迟加载策略
    本文深入分析了Hibernate延迟加载的机制,特别是集合属性的延迟加载策略。通过延迟加载,可以降低系统的内存开销,提高Hibernate的运行性能。对于集合属性,推荐使用延迟加载策略,即在系统需要使用集合属性时才从数据库装载关联的数据,避免一次加载所有集合属性导致性能下降。 ... [详细]
author-avatar
建哥2502897913
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有