首页
学习
活动
专区
圈层
工具
发布

Javascript运行机制(Event loop)原理知道吗?不懂就来看看吧,一篇文章让你搞定

进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。 队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。...因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO—first in first out) 什么是Event loop?...)队列中为空时,执行宏任务(Tasks) 执行 setTimeout callback 打印结果:setTimeout 最后一次执行 清空Tasks队列和JS stack 下面再来一个比较复杂的例子...每次我们使用 await, 解释器都创建一个 promise 对象,然后把剩下的 async 函数中的操作放到 then 回调函数中。 async/await 的实现,离不开 Promise。...然后先执行打印promise1,此时then的回调函数返回undefinde,此时又有then的链式调用,又放入微任务队列中,再次打印promise2。

84040

一张图带你搞懂Node事件循环

事件循环在不同的操作系统里有一些细微的差异。这将涉及到操作系统的知识,暂时不表。 本次只介绍JS主线程中,Node的运作流程。Node的其他线程暂时也不扩展。 事件循环图 说好的一张图,也不卖关子。...当某个计时器检查通过,则执行其回调函数。 poll队列的运作方式 如果poll中有回调函数需要执行,依次执行回调,直到清空队列。 如果poll中没有回调函数需要执行,已经是空队列了。...到达timers队列,发现有回调函数任务,则依次执行回调,清空timers队列(当然这里只有一个5秒到达后的回调,所以直接执行完了即可),打印出“setTimeout”。...还有在timers队列里,对于计时器线程中各个定时任务的计算时间。 结合poll队列的面试题(考察timers、poll和check的执行顺序) 如果你看懂了上边的事件循环图,下边这道题难不倒你!...:清空Promise队列的过程中,遇到nextTick微任务,立即执行、清空 setTimeout 0: 解释第一个问题.

1.8K22
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    4.并发编程多线程

    当我们的程序是偏计算的,也就是cpu占用率很高的程序(cpu一直在计算),就不行了,但是如果你的程序是I/O型的(一般你的程序都是这个)(input、访问网址网络延迟、打开/关闭文件读写),在什么情况下用的到高并发呢...详解: 因为Python解释器帮你自动定期进行内存回收,你可以理解为python解释器里有一个独立的线程,每过一段时间它起wake up做一次全局轮询看看哪些内存数据是可以被清空的,此时你自己的程序 里的线程和...py解释器自己的线程是并发运行的,假设你的线程删除了一个变量,py解释器的垃圾回收线程在清空这个变量的过程中的clearing时刻,可能一个其它线程正好又重新给这个还没来及得清空的内存空间赋值了,结果就有可能新赋值的数据被删除了...() conn2.start() check.start() 十四 线程队列   线程之间的通信我们列表行不行呢,当然行,那么队列和列表有什么区别呢?   ...,取过的就不再取了 #结果分析: 打印的结果是没有顺序的,因为到了func函数中的sleep的时候线程会切换,谁先打印就没准儿了,但是最后的我们通过结果对象取结果的时候拿到的是有序的,因为我们主线程进行

    92310

    可视化的 js:动态图演示 Promises & AsyncAwait 的过程!

    让我们为脚本添加一些更多的代码并且再次运行它: 等下,发生了什么?! 首先,Start! 被输出。 好的,我们已经看到了那一个即将到来的消息:console.log('Start!')...(微任务自己也能返回一个新的微任务,有效地创建无限的微任务循环 ) 如果调用栈和微任务队列都是空的,事件循环会检查宏任务队列里是否还有任务。...如果宏任务中还有任务,会从宏任务队列中弹出进入调用栈,被执行后会从调用栈中弹出! 让我们快速地看一个简单的例子: Task1: 立即被添加到调用栈中的函数,比如在我们的代码中立即调用它。...它们是内部的方法实际上没有出现在堆栈痕迹中,因此如果你正在使用调试器,不用担心,你不会在任何地方见到它们。它只是在没有添加一堆样本文件代码的情况下使这个概念解释起来更加简单。...被打印到控制台并且console.log从调用栈弹出。 最终,所有的事情都完成了!你注意到async函数相比于promise的then有什么不同吗?

    2.7K10

    带你彻底弄懂Event Loop前言正文总结

    ,如果对你有用,就请给个Star吧~) 正文 Event Loop是什么 event loop是一个执行模型,在不同的地方有不同的实现。...等); 全局Script代码执行完毕后,调用栈Stack会清空; 从微队列microtask queue中取出位于队首的回调任务,放入调用栈Stack中执行,执行完后microtask queue长度减...我们来一起分析一下: 执行全局Script代码,先打印start,向下执行,将setTimeout的回调callback1注册到Timers Queue中,再向下执行,将setImmediate的回调callback5...先执行全局Script代码,执行完同步代码调用栈清空后,先从微任务队列Next Tick Queue中依次取出所有的任务放入调用栈中执行,再从微任务队列Other Microtask Queue中依次取出所有的任务放入调用栈中执行...先执行全局Script代码,执行完同步代码调用栈清空后,先从微任务队列Next Tick Queue中依次取出所有的任务放入调用栈中执行,再从微任务队列Other Microtask Queue中依次取出所有的任务放入调用栈中执行

    80640

    第37天并发编程之线程篇

    线程初识 什么是线程和进程 进程指的是一个程序执行的过程,是一个资源单位。它包含了操作系统开辟内存空间,将应用程序加载到内存中以及执行应用程序代码的整个过程。...进程之间内存是物理隔离的,但是同一进程内的线程之间内存是共享的。注意不同进程之间的线程通信还是需要通过队列进行通信的。...() for i in t_l: i.join() print(x) 5.GIL全局解释器锁 python程序执行的三个步骤 (1)....将内存中的程序传递给python解释器一步一步执行 问题:为什么多个线程不能同时使用一个python解释器呢?...,这也就解释了回调的意思,我来调用你,结果给我之后就应该就由我来解析 obj.add_done_callback(parse) 多线程和多进程的方式都是一样的,唯一不同的地方就在于回调函数是哪个线程空闲哪个线程去执行回调函数

    52430

    带你彻底弄懂Event Loop

    ,如果对你有用,就请给个Star吧~) 正文 Event Loop是什么 event loop是一个执行模型,在不同的地方有不同的实现。...等); 全局Script代码执行完毕后,调用栈Stack会清空; 从微队列microtask queue中取出位于队首的回调任务,放入调用栈Stack中执行,执行完后microtask queue长度减...具体可以通过下图加深一下理解: 大体解释一下NodeJS的Event Loop过程: 执行全局Script的同步代码 执行microtask微任务,先执行所有Next Tick Queue中的所有任务...先执行全局Script代码,执行完同步代码调用栈清空后,先从微任务队列Next Tick Queue中依次取出所有的任务放入调用栈中执行,再从微任务队列Other Microtask Queue中依次取出所有的任务放入调用栈中执行...先执行全局Script代码,执行完同步代码调用栈清空后,先从微任务队列Next Tick Queue中依次取出所有的任务放入调用栈中执行,再从微任务队列Other Microtask Queue中依次取出所有的任务放入调用栈中执行

    55410

    宏任务是异步还是同步?再谈事件循环

    即便是在 JavaScript 中,也存在浏览器和 Node 两种不同的事件循环机制。可见,事件循环是一个概念,不同技术对它的实现细节不尽相同。实际上,事件循环驱动着浏览器中发生的一切。...在下面 3 个时机,宏任务会被添加到任务队列:一段新程序或子程序被直接执行时,例如一个 元素中运行代码。触发了一个事件,将其回调函数添加到任务队列时。...什么是堆栈溢出(Stack Overflow)当递归函数调用次数过多,超过调用栈的最大容量时,就会发生堆栈溢出(Stack Overflow)。...为什么 setTimeout(fn(),1000) 中 fn() 不一定是延迟 1 秒执行?setTimeout 的第 2 个参数指的是回调函数被加入任务队列的延迟时间。...但是,如果任务队列或调用栈不为空,则需要等待队列前面的任务执行完或调用栈清空,才轮到 setTimeout 的回调函数。

    70211

    补充一:C#中的Queue

    最后,通过Dequeue按照FIFO原则逐个处理队列中的元素。 解释代码中的关键点: Enqueue方法用于将元素添加到队列的末尾。 Dequeue方法用于从队列的开头移除并返回元素。...2.3 清空队列 在C#中,可以使用 Clear 方法来清空队列中的所有元素。...清空后,再次通过迭代整个队列,可以看到队列已经为空。 关键点解释: Clear 方法用于清空队列中的所有元素。 清空队列后,Count 属性将变为0。...清空队列通常在需要重新使用队列之前执行,以确保没有残留的元素。 2.4 复制队列 在C#中,可以使用 Queue 类的构造函数或 ToArray 方法来创建一个队列的副本。...无论使用哪种方法,都可以确保在复制过程中不影响原始队列的结构。 关键点解释: 使用 Queue 构造函数或 ToArray 方法可以创建原始队列的副本。

    76010

    【面试题】734- 从一道面试题谈谈对 EventLoop 的理解

    进行插入操作的端称为队尾,进行删除操作的端称为队头。 队列中没有元素时,称为空队列。 队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。...js中的堆栈队列 下面我解释下JavaScript语言中的堆、栈、队列。...小结 先总结一波个人对于JS运行机制的理解: 代码执行开启一个全局调用栈(主栈)提供代码运行的环境,在执行过程中同步任务的代码立即执行,遇到异步任务将异步的回调注册到任务队列中,等待同步代码执行完毕查看异步是否完成...HTTP 请求线程 负责执行异步请求 主线程执行代码遇到异步请求的时候会把函数交给该线程处理,当监听到状态变更事件,如果有回调函数,该线程会把回调函数加入到任务队列的队尾等待执行 Event Loop...个人理解的执行顺序: 代码从开始执行调用一个全局执行栈,script标签作为宏任务执行 执行过程中同步代码立即执行,异步代码放到任务队列中,任务队列存放有两种类型的异步任务,宏任务队列,微任务队列。

    1K31

    一次弄懂Event Loop(彻底解决此类面试问题)

    进行插入操作的端称为队尾,进行删除操作的端称为队头。 队列中没有元素时,称为空队列。 队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。...每次我们使用 await, 解释器都创建一个 promise 对象,然后把剩下的 async 函数中的操作放到 then 回调函数中。 async/await 的实现,离不开 Promise。...然后先执行打印promise1,此时then的回调函数返回undefinde,此时又有then的链式调用,又放入微任务队列中,再次打印promise2。...再回到await的位置执行返回的 Promise 的 resolve 函数,这又会把 resolve 丢到微任务队列中,打印async1 end。...换种理解方式: 当每个阶段完成后,如果存在 nextTick 队列,就会清空队列中的所有回调函数,并且优先于其他 microtask 执行。

    83610

    前端面试之JavaScript

    1.全局作用域:代码在程序的任何地方都能被访问,window 对象的内置属性都拥有全局作用域。...优点是可以读取函数内部的变量,让这些变量的值始终保存在内存中,不会在函数被调用之后自动清除 闭包形成的条件: 函数的嵌套 内部函数引用外部函数的局部变量,延长外部函数的变量生命周期 闭包的用途...在浏览器环境中,有JS 引擎线程和渲染线程,且两个线程互斥。 Node环境中,只有JS 线程。 不同环境执行机制有差异,不同任务进入不同Event Queue队列。...Stack为空; 此期间WebAPIs完成这个事件,把回调函数放入队列中等待执行(微任务放到微任务队列,宏任务放到宏任务队列) 执行栈为空时,Event Loop把微任务队列执行清空; 微任务队列清空后...,进入宏任务队列,取队列的第一项任务放入Stack(栈)中执行,执行完成后,查看微任务队列是否有任务,有的话,清空微任务队列。

    1K20

    爬虫进阶Python多线程和多进程

    每个CPU在同一时间只能执行一个线程 GIL的全称是Global Interpreter Lock(全局解释器锁),就相当于通行证,每一次线程会先要去申请通行证,通行证申请下来了,才能进入CPU...并且由于GIL锁存在,python里一个进程永远只能同时执行一个线程(拿到GIL的线程才能执行),这就是为什么在多核CPU上,python的多线程效率并不高。 下面使用多线程加队列做的一个demo。...考虑这样一种情况:一个列表里所有元素都是0,线程”set”从后向前把所有元素改成1,而线程”print”负责从前往后读取列表并打印。...那么,可能线程”set”开始改的时候,线程”print”便来打印列表了,输出就成了一半0一半1,这就是数据的不同步。为了避免这种情况,引入了锁的概念。 锁有两种状态——锁定和未锁定。...Queue模块中的常用方法: Queue.qsize() 返回队列的大小 Queue.empty() 如果队列为空,返回True,反之False Queue.full() 如果队列满了,返回True,反之

    1.3K40

    JavaScript引擎是如何工作的?从调用栈到Promise你需要知道的一切

    调用栈是一个栈数据结构:这意味着元素可以从顶部进入,但如果在它们上面还有一些元素,就不能离开栈。 JavaScript 函数就是这样的。...异步JavaScript,回调队列和事件循环 全局内存、执行上下文和调用栈解释了同步 JavaScript 代码在浏览器中的运行方式。然而我们还错过了一些东西。当有异步函数运行时会发生什么?...此时我们的 JavaScript 引擎中还有两个框。...如果你喜欢视频,我建议去看 Philip Roberts 的视频:事件循环是什么。这是关于时间循环的最好的解释之一。...但是在 Promise 中传递的回调函数有不同的命运:它们由微任务队列处理,而不是由回调队列处理。 你应该注意一个有趣的现象:微任务队列优先于回调队列。

    1.9K30

    2年前端面试打怪升级之路

    ;遇到Promise,首先执行里面的同步代码,打印出2,遇到resolve,将其加入到微任务队列,执行后面同步代码,打印出3;继续执行script中的代码,打印出7和8,至此第一轮代码执行完成;执行微任务队列中的代码...,首先打印出4,如遇到Promise,执行其中的同步代码,打印出5,遇到定时器,将其加入到宏任务队列中,此时宏任务队列中有两个定时器;执行宏任务队列中的代码,这里我们需要注意是的第一个定时器的时间为100ms...不同的任务源会被分配到不同的 Task 队列中,任务源可以分为 微任务(microtask) 和 宏任务(macrotask)。...this的,它的this来自原其父级所处的上下文,所以首先会打印全局中的 a 的值10。...标准答案更正确的解释什么是原型链?

    44130

    事件循环的秘密,竟然影响着浏览器的一切!

    用事件循环去解释这段代码就非常明白了。 那你肯定会想,这些任务难道都没有优先级吗? 对的,任务没有优先级,在消息队列中先进先出,但消息队列是有优先级的。...根据 W3C 的最新解释哈 : 每个任务都有一个任务类型,同一个类型的任务必须在一个队列,不同类型的任务可以分属于不同的队列。 在一次事件循环中,浏览器可以根据实际情况从不同的队列中取出任务执行。...例如 Promise.resolve().then(函数) 浏览器还有很多其他的队列,由于和我们开发关系不大,暂时不作考虑。 下面我们来具体看一些代码例子,来辅助理解 队列的优先级 问题。...根据WBC官方的解释,每个任务有不同的类型,同类型的任务必须在同一个队列,不同的任务可以属于不同的队列。不同任务队列有不同的优先级,在一次事件循环中,由浏览器自行决定取哪一个队列的任务。...但浏览器必须有一个微队列,微队列的任务一定具有最高的优先级,必须优先调度执行。 面试题: JS中的计时器能做到精确计时吗? 为什么?

    67210

    新生代总结 JavaScript 运行机制解析

    其实这个问题就出现在了 JavaScript 的应用场景上,我们通常采用 JavaScript 来操作 DOM 元素,这在现在来看没什么问题。...想象一下下面的场景 一段 JS 代码删除 DOM 元素,一段 JS 代码更改 DOM 元素样式,它们一起被执行了,这会发生什么?...在 JavaScript 中还有着独特执行机制,它将主线程中的任务分为同步任务和异步任务 2. 为什么需要异步?...当执行栈中的同步任务执行完毕后,先执行微任务 微任务队列执行完毕后,会读取宏任务 执行宏任务的过程中,遇到微任务,再加入微任务队列 宏任务执行完后,再次读取微任务队列,依次循环 画个图来辅助理解一下...第五轮循环 首先清空微任务队列,执行打印语句,打印 10 执行完毕 以上就是关于 JavaScript 运行机制的全部内容,希望能有所收获 非常感谢您的阅读,欢迎提出你的意见,有什么问题欢迎指出,

    49320

    新生代总结 JavaScript 运行机制解析

    其实这个问题就出现在了 JavaScript 的应用场景上,我们通常采用 JavaScript 来操作 DOM 元素,这在现在来看没什么问题。...想象一下下面的场景 一段 JS 代码删除 DOM 元素,一段 JS 代码更改 DOM 元素样式,它们一起被执行了,这会发生什么?...在 JavaScript 中还有着独特执行机制,它将主线程中的任务分为同步任务和异步任务 2. 为什么需要异步?...当执行栈中的同步任务执行完毕后,先执行微任务 微任务队列执行完毕后,会读取宏任务 执行宏任务的过程中,遇到微任务,再加入微任务队列 宏任务执行完后,再次读取微任务队列,依次循环 画个图来辅助理解一下...第五轮循环 首先清空微任务队列,执行打印语句,打印 10 执行完毕 以上就是关于 JavaScript 运行机制的全部内容,希望能有所收获 非常感谢您的阅读,欢迎提出你的意见,有什么问题欢迎指出,

    57130
    领券