当前位置: 首页 > news >正文

浏览器和node某方面执行顺序不一样

setTimeout(function() {

console.log('1');

new Promise(function(resolve) {

console.log('2');

resolve();

}).then(function() {

console.log('3')

})

})

 

new Promise(function(resolve) {

console.log('4');

resolve();

}).then(function() {

console.log('5')

})

 

 

 

关于浏览器和node环境下的事件环差异

96 不净莲华 关注

2019.01.27 22:38* 字数 777 阅读 101评论 0喜欢 0

javascript在近些年在web端的作用越来越强大,不仅在浏览器端占据主导地位,在服务端也有一席之地,node.js做为以javascript语法作为服务端语言,而javascript作为一种单线程语言,为实现主线程的不阻塞,Event Loop方案孕育而生,浏览器和node中Event loop并不一样,浏览器的Event loop是在HTML5中定义的规范,而node中则由libuv库实现。

浏览器中的Event loop

  • 浏览器的任务队列分为宏任务和微任务
    • 宏任务:setTimeout, setInterval, setImmediate, I/O,原生事件回调函数,MessageChannel、postMessage等。
    • 微任务:process.nextTick, 原生Promise(有些实现的promise将then方法放到了宏任务中),Object.observe(已废弃), MutationObserver等。

那么浏览器中的任务执行顺序是怎么样的呢?

  1. 浏览器中,先执行当前栈,执行完主执行线程中的任务。
  2. 取出Microtask微任务队列中任务执行直到清空。
  3. 取出Macrotask宏任务中 一个 任务执行。
  4. 检查Microtask微任务中有没有任务,如果有任务执行直到清空。
  5. 重复3和4。

整个的这种运行机制又称为Event Loop(事件循环)

node中的Event loop

  • 在libuv内部有这样一个事件环机制。在node启动时会初始化事件环。
  • node中的event loop分为6个阶段,不同于浏览器的是,这里每一个阶段都对应一个事件队列,node会在当前阶段中的全部任务执行完,清空NextTick Queue,清空Microtask Queue,再执行下一阶段。
  • 在node.js里,process 对象代表node.js应用程序,可以获取应用程序的用户,运行环境等各种信息。process.nextTick()方法将 callback 添加到next tick 队列,并且nextTick优先级比promise等microtask高。
  1. timers:执行setTimeout() 和 setInterval()中到期的callback。
  2. I/O callbacks:上一轮循环中有少数的I/Ocallback会被延迟到这一轮的
  3. 这一阶段执行 idle, prepare:队列的移动,仅内部使用
  4. poll:最为重要的阶段,执行I/O callback,在适当的条件下会阻塞在这个阶段
  5. check:执行setImmediate的callback
  6. close callbacks:执行close事件的callback,例如socket.on("close",func)

总结

  • 同一个上下文下,MicroTask微任务会比MacroTask宏任务先运行。
  • 浏览器是先取出一个MacroTask宏任务执行,再执行MicroTask微任务中的所有任务。Node是按照六个阶段执行,每个阶段切换时,再执行MicroTask微任务队列
  • 同个MicroTask队列下process.tick()会优于Promise
  • setImmdieate()和setTimeout(),如果他们在异步i/o callback之外调用(在i/o内调用因为下一阶段为check阶段),其执行先后顺序是不确定的,需要看loop的执行前的耗时情况。

 

setTimeout(function() {

console.log('6');

})

浏览器 :4 5 1 2 3 6

node: 4 5 1 2 6 3 。 node 同级微任务>同级宏任务>宏任务中微任务> 微任务中宏任务

 

事件循环
nodejs
基于node.js的事件循环分析,每一次循环就是一次tick,每一次tick时,v8引擎从事件队列中取出所有事件依次进行处理,如果遇到nextTick事件,则将其加入到事件队尾,等待下一次tick到来时执行;造成的结果是,nextTick事件被延迟执行

浏览器解析js

Event Queue 有两个,一个宏任务的,一个微任务的,先执行微任务的,然后执行宏任务,
宏任务就是开始了下一个循环

相关文章:

  • 大餐还是鸡肋?让我们谈谈Flash Lite
  • gulp中的同步异步问题
  • 小试一把 64 位 Windows 编程
  • 什么是options请求?为什么会有options请求?
  • 网站完全恢复
  • rel=noopener可以提升性能
  • node.js开发:nodemon
  • 网站备份策略
  • web前端: Vue cli3 库模式搭建组件库并发布到 npm
  • 整理一个坛子里的笑话...稍微改编一下,就叫做《MM和一个程序员相亲的故事》!...
  • JQuery Delegate IOS上失效解决方案
  • deplate(Viki) 全面定制
  • webpack-dev-server默认打开指定chrome浏览器的方式
  • 发现CSDN给我开了一个专栏!
  • vue 组件预览图片
  • android图片蒙层
  • Apache Pulsar 2.1 重磅发布
  • ECS应用管理最佳实践
  • emacs初体验
  • Java基本数据类型之Number
  • js对象的深浅拷贝
  • log4j2输出到kafka
  • PAT A1017 优先队列
  • php的插入排序,通过双层for循环
  • React Transition Group -- Transition 组件
  • Redis 中的布隆过滤器
  • Shadow DOM 内部构造及如何构建独立组件
  • vue 个人积累(使用工具,组件)
  • 闭包--闭包作用之保存(一)
  • 从零开始在ubuntu上搭建node开发环境
  • 给新手的新浪微博 SDK 集成教程【一】
  • 官方新出的 Kotlin 扩展库 KTX,到底帮你干了什么?
  • 后端_ThinkPHP5
  • 基于MaxCompute打造轻盈的人人车移动端数据平台
  • 一个普通的 5 年iOS开发者的自我总结,以及5年开发经历和感想!
  • 与 ConTeXt MkIV 官方文档的接驳
  • 《码出高效》学习笔记与书中错误记录
  • Java性能优化之JVM GC(垃圾回收机制)
  • shell使用lftp连接ftp和sftp,并可以指定私钥
  • 分布式关系型数据库服务 DRDS 支持显示的 Prepare 及逻辑库锁功能等多项能力 ...
  • ​创新驱动,边缘计算领袖:亚马逊云科技海外服务器服务再进化
  • ​渐进式Web应用PWA的未来
  • (12)Hive调优——count distinct去重优化
  • (20050108)又读《平凡的世界》
  • (day6) 319. 灯泡开关
  • (PHP)设置修改 Apache 文件根目录 (Document Root)(转帖)
  • (python)数据结构---字典
  • (zhuan) 一些RL的文献(及笔记)
  • (二)丶RabbitMQ的六大核心
  • (附源码)spring boot北京冬奥会志愿者报名系统 毕业设计 150947
  • (附源码)计算机毕业设计高校学生选课系统
  • (六)库存超卖案例实战——使用mysql分布式锁解决“超卖”问题
  • (十八)devops持续集成开发——使用docker安装部署jenkins流水线服务
  • (十一)JAVA springboot ssm b2b2c多用户商城系统源码:服务网关Zuul高级篇
  • .net CHARTING图表控件下载地址