微任务

Event Loop事件循环,GET!

爷,独闯天下 提交于 2020-02-03 18:26:58
JS中比较让人头疼的问题之一要算异步事件了,比如我们经常要等后台返回数据后进行dom操作,又比如我们要设置一个定时器完成特定的要求。在这些同步与异步事件里,异步事件肯定是在同步事件之后的,但是异步事件之间又是怎么样的一个顺序呢,比如多个setTimeout事件又是怎么样一个执行顺序?这就涉及到事件循环:Event Loop。 JS的单线程 虽然现在的JS可以用来做多方面的开发,但是最初的JS是浏览器的专用语言,用来操作DOM。所以从诞生之初,JS就被设计成单线程语言,原因是不想让浏览器变得太复杂,因为多线程需要共享资源、且有可能修改彼此的运行结果,对于一种网页脚本语言来说,这就太复杂了。如果 JavaScript 同时有两个线程,一个线程在网页 DOM 节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?是不是还要有锁机制?所以,为了避免复杂性,JavaScript 一开始就是单线程,这已经成了这门语言的核心特征,将来也不会改变。 但是这种单线程机制却制造了另一个麻烦,假如一个操作需花费很长时间,那么此时浏览器就会一直等待这个操作完成,就会造成不好的体验。因此,JS的另一个事件就是异步事件。异步事件是专门将一些事件以队列的形式储存到浏览器的任务队列中,等同步事件执行完后再去执行,这样就避免了页面堵塞。 JavaScript 引擎怎么知道异步任务有没有结果

JS浏览器事件循环机制

帅比萌擦擦* 提交于 2020-02-01 01:50:27
先来明白些概念性内容。 进程、线程 进程是系统分配的独立资源,是 CPU 资源分配的基本单位,进程是由一个或者多个线程组成的。 线程是进程的执行流,是CPU调度和分派的基本单位,同个进程之中的多个线程之间是共享该进程的资源的。 浏览器内核 浏览器是多进程的,浏览器每一个 tab 标签都代表一个独立的进程(也不一定,因为多个空白 tab 标签会合并成一个进程),浏览器内核(浏览器渲染进程)属于浏览器多进程中的一种。 浏览器内核有多种线程在工作。 GUI 渲染线程: 负责渲染页面,解析 HTML,CSS 构成 DOM 树等,当页面重绘或者由于某种操作引起回流都会调起该线程。 和 JS 引擎线程是互斥的,当 JS 引擎线程在工作的时候,GUI 渲染线程会被挂起,GUI 更新被放入在 JS 任务队列中,等待 JS 引擎线程空闲的时候继续执行。 JS 引擎线程: 单线程工作,负责解析运行 JavaScript 脚本。 和 GUI 渲染线程互斥,JS 运行耗时过长就会导致页面阻塞。 事件触发线程: 当事件符合触发条件被触发时,该线程会把对应的事件回调函数添加到任务队列的队尾,等待 JS 引擎处理。 定时器触发线程: 浏览器定时计数器并不是由 JS 引擎计数的,阻塞会导致计时不准确。 开启定时器触发线程来计时并触发计时,计时完成后会被添加到任务队列中,等待 JS 引擎处理。 http 请求线程:

10分钟理解JS引擎的执行机制

爷,独闯天下 提交于 2020-01-30 21:29:18
10分钟理解JS引擎的执行机制 javascript 阅读约 7 分钟 深入理解JS引擎的执行机制 1.灵魂三问 : JS为什么是单线程的? 为什么需要异步? 单线程又是如何实现异步的呢? 2.JS中的event loop(1) 3.JS中的event loop(2) 4.说说setTimeout 首先,请牢记2点: (1) JS是单线程语言 (2) JS的Event Loop是JS的执行机制。深入了解JS的执行,就等于深入了解JS里的event loop 1.灵魂三问 : JS为什么是单线程的? 为什么需要异步? 单线程又是如何实现异步的呢? 技术的出现,都跟现实世界里的应用场景密切相关的。 同样的,我们就结合现实场景,来回答这三个问题 (1) JS为什么是单线程的? JS最初被设计用在浏览器中,那么想象一下,如果浏览器中的JS是多线程的。 场景描述: 那么现在有2个线程,process1 process2,由于是多线程的JS,所以他们对同一个dom,同时进行操作 process1 删除了该dom,而process2 编辑了该dom,同时下达2个矛盾的命令,浏览器究竟该如何执行呢? 这样想,JS为什么被设计成单线程应该就容易理解了吧。 (2) JS为什么需要异步? 场景描述: 如果JS中不存在异步,只能自上而下执行,如果上一行解析时间很长,那么下面的代码就会被阻塞。 对于用户而言

EventLoop

空扰寡人 提交于 2020-01-29 16:12:36
文章资料来自 Node.js 事件循环机制 JS灵魂之问(下) EventLoop的中国名字叫事件循环,这个玩意真的是高深莫测,一般开发都用不到,代码只管写就行,虽然不用懂,但是面试就是要问,这对我这种小菜鸡真是满满的恶意 先说说异步IO 这个在Linux笔记里有,但是异步IO只有 Linux 下存在,在其他系统中没有异步 IO 支持,那window的异步IO是怎么实现的,==利用多线程==,我们可以让一个进程进行计算操作,另外一些进行 IO 调用,IO 完成后把信号传给计算的线程,进而执行回调,这不就好了吗?没错,异步 IO 就是使用这样的==线程池==来实现的,只不过在不同的系统下面表现会有所差异,在 Linux 下可以直接使用==线程池==来完成,在Window系统下则采用 IOCP 这个系统API(其内部还是用==线程池==完成的) 上面的三个线程池都加粗了,因为他就是关键字,线程池的运行图很常见 V8、事件循环、事件队列都在单线程中运行,最右侧还有工作线程(Worker Thread)负责提供异步的I/O操作,这就是为什么说Node.js拥有非阻塞的,事件驱动的异步IO架构 不仅是异步IO运行在线程池,NodeJS的计时器,http请求,浏览器的计时器,http请求ajax,ui渲染也都是运行在线程池的,也就是说==js是单线程运行是错的==,他是==同步任务单线程运行=

定时器 setTimeout & setInterval

≡放荡痞女 提交于 2020-01-25 05:18:27
setTimeout和setInteval是window对象上两个主要的定时方法,他们的语法基本相同,但完成功能的却是不同的。 settimeout方法是定时程序,也就是在到达某个指定时间后,执行什么事。(执行一次就拉倒) setinterval方法则是表示间隔一定时间反复执行某些事。 定时器的返回值 当我们设置定时器时(不管是setTimeout还是setInterval),都会有一个返回值。这个返回值是一个数字,代表当前是在浏览器中设置的第几个定时器(返回的是定时器序号)。 let timer1 = setTimeout ( ( ) => { } , 1000 ) console . log ( timer1 ) // 1 let timer2 = setInterval ( ( ) => { } , 1000 ) console . log ( timer2 ) // 2 根据上面两端代码可以知道 1.setTimeout和setInterval虽然是处理不同功能的定时器,但都是浏览器的定时器,所以返回的序号是依次排列的。 2.setInterval设置完成定时器会有一个返回值,不管执行多少次,这个代表序号的返回值不变(设置定时器就有返回值,执行多少次是定时器的处理)。 定时器的清除 clearTimeout([定时器的排队序号]) clearInterval(

Javascript 异步实现 & 事件循环

不问归期 提交于 2020-01-24 22:37:20
浏览器的进程和线程 一、js的单线程和异步 js的单线程(single threaded)和异步(asynchronous)两个基本矛盾的概念是怎么整合到js上的 首先必须肯定js本身不可能是异步的,但js的宿主环境(比如浏览器,Node)是多线程的 宿主环境通过某种方式(事件驱动)使得js具备了异步的属性 二、浏览器的进程 浏览器的主进程 :负责协调、主控 第三方插件进程 :每种类型的插件对应一个进程,仅当使用该插件时才创建 GPU进程 :最多一个,用于3D绘制等 浏览器渲染进程 (浏览器内核):主要作用为页面渲染,脚本执行,事件处理等 三、浏览器内核线程 1、JS引擎线程 JS引擎一直等待着任务队列中任务的到来,然后加以处理 一个Tab页中无论什么时候都只有一个JS引擎在运行JS程序 2、GUI渲染线程 GUI渲染线程与JS引擎线程是互斥的 当JS引擎执行时GUI线程会被挂起 GUI更新会被保存在一个队列中等到JS引擎空闲时执行 3、定时器线程 传说中的setInterval与setTimeout所在线程 二者的定时计数功能不是由JS引擎完成的,而是通过 单独的线程 来完成的,从而保证计时准确 计时完毕,将回调添加到事件队列中,等待JS引擎空闲执行 4、事件触发线程 点击事件等会在对应条件触发的时候被添加到事件队列,等js引擎空闲执行

浏览器和Node 事件循环的区别

≡放荡痞女 提交于 2020-01-19 11:59:57
题目描述: 浏览器和Node 事件循环的区别 解题: 思路一: 其中一个主要的区别在于浏览器的event loop 和nodejs的event loop 在处理异步事件的顺序是不同的,nodejs中有micro event;其中Promise属于micro event 该异步事件的处理顺序就和浏览器不同.nodejs V11.0以上 这两者之间的顺序就相同了 function test () { console.log('start') setTimeout(() => { console.log('children2') Promise.resolve().then(() => {console.log('children2-1')}) }, 0) setTimeout(() => { console.log('children3') Promise.resolve().then(() => {console.log('children3-1')}) }, 0) Promise.resolve().then(() => {console.log('children1')}) console.log('end') } test() // 以上代码在node11以下版本的执行结果(先执行所有的宏任务,再执行微任务) // start // end // children1 //

Event Loop原理

纵然是瞬间 提交于 2020-01-16 05:56:51
文章目录 前言 event loop 宏任务&微任务 附录 前言 灵魂三问 JS为什么是单线程的 ? JS最初被设计用在浏览器中,那么想象一下,如果浏览器中的JS是多线程的。 场景描述: 那么现在有2个进程,process1 process2,由于是多进程的JS,所以他们对同一个dom,同时进行操作 process1 删除了该dom,而process2 编辑了该dom,同时下达2个矛盾的命令,浏览器究竟该如何执行呢? 为什么需要异步 ? 如果JS中不存在异步,只能自上而下执行,如果上一行解析时间很长,那么下面的代码就会被阻塞。 对于用户而言,阻塞就意味着"卡死",这样就导致了很差的用户体验 单线程又是如何实现异步的呢 ? 既然JS是单线程的,只能在一条线程上执行,又是如何实现的异步呢? 答案就是**是通过的事件循环(event loop)** event loop javascript 是一门单线程的脚本语言,也就意味着同一个时间只能做一件事,但是单线程有一个问题:一旦这个线程被阻塞就无法继续工作了,这肯定是不行的。由于异步编程可以实现 非阻塞 的调用效果,引入异步编程自然就是顺理成章的事情了。 从同步异步来理解JS的执行机制 console.log(1) setTimeout(function(){ console.log(2) },0) console.log(3)

三.[前端总结]之浏览器篇

家住魔仙堡 提交于 2020-01-15 00:47:05
1. 跨标签⻚通讯 不同标签⻚间的通讯,本质原理就是去运⽤⼀ 些可以 共享的中间介质 ,因此⽐较常⽤的有以下⽅法: 通过 ⽗⻚⾯ window.open() 和⼦⻚⾯ postMessage   异步下, 通过 window.open('about: blank') 和 tab.location.href = '*' 设置同域下 共享的 localStorage 与 监听 window.onstorage   重复写⼊相同的值⽆法触发   会受到浏览器隐身模式等的限制 设置共享 cookie 与不断轮询脏检查( setInterval ) 借助服务端或者中间层实现 2. 浏览器架构 ⽤户界⾯ 主进程内核   渲染引擎   JS 引 擎     执⾏栈 事件触发线程   消息队列     微任务     宏任务 ⽹络异步线程 定时器线程 3.浏览器下事件循环(Event Loop) 事件循环是指: 执⾏⼀个宏任务,然后执⾏清空微任务列表,循环再执⾏宏任务,再清微任务列表 微任务 microtask(jobs): promise / ajax / Object.observe (该⽅法已废弃) 宏 任 务 macrotask(task): setTimout / script / IO / UI Rendering 4.从输 ⼊ url 到展示的过程 DNS 解 析 TCP 三次握⼿

浅谈 Event loop (事件循环)

痴心易碎 提交于 2020-01-11 03:52:09
从Event Loop谈JS的运行机制 先来理解一个概念: JS分为同步任务和异步任务 同步任务都在主线程上执行,形成一个 执行栈 Execute Content Stack 主线程之外, 事件触发线程 管理着一个 任务队列 ,只要异步任务有了运行结果,就在 任务队列(根据MDN准确的说应该是 消息队列 message queue ) 之中放置一个消息(一般都是异步的回调函数)。 一旦 执行栈 中的所有同步任务执行完毕(此时JS引擎空闲),系统就会读取 消息队列 ,将可运行的异步任务添加到可执行栈中,开始执行。 看图: 看到这里,应该就可以理解了:为什么有时候setTimeout推入的事件不能准时执行?因为可能在它推入到 消息队列 时,主线程还不空闲,正在执行其它代码,所以自然有误差。 事件循环机制进一步补充 这里就直接引用一张图片来协助理解:(参考自Philip Roberts的演讲《Help, I’m stuck in an event-loop》) 上图大致描述就是: 主线程运行时会产生执行栈,栈中的代码调用某些api时,它们会在事件队列中添加各种事件(当满足触发条件后,如ajax请求完毕) 而栈中的代码执行完毕,就会读取事件队列中的事件到执行栈中,去执行那些回调 如此循环 注意,总是要等待栈中的代码执行完毕后才会去读取消息队列中的消息 然后我们通过阅读Promise/A