前端-题目集合

 

一、前端开发:JS事件循环机制 

1. 什么是js的事件循环

事件循环就是JS代码的运行机制。
另:
异步操作的触发, 其实是 同步执行的。
而回调函数的触发,是异步执行的

JavaScript事件循环是一种处理异步事件和回调函数的机制,它是JavaScript实现异步编程的核心。它会不断地从任务队列中取出任务并执行,直到任务队列为空为止。事件循环中的任务分为同步任务和异步任务,异步任务又可以分为宏任务和微任务,微任务的执行优先级高于宏任务。

 

2. 为什么会出现js的事件循环

JavaScript事件循环是为了解决JavaScript作为单线程语言时的并发性问题而设计的。由于JavaScript是单线程的,因此在执行代码时不能同时执行多个任务。这种单一线程的特性可能会导致JavaScript在处理某些长时间运行的操作(如网络请求、文件系统访问等)时出现阻塞,从而影响用户体验。
为了解决这些问题,JavaScript引入了异步编程模型和事件循环机制,它可以监听消息队列中的事件并根据优先级顺序依次执行相应的回调函数。这种机制允许JavaScript在等待某些操作完成的同时,可以执行其他任务,从而避免了阻塞,提高了效率和并发性,使得开发者可以使用异步编程模型来处理复杂的、长时间运行的操作,同时提供更好的用户体验。

3.事件循环的流程

事件循环中的任务分为两类:同步任务和异步任务。同步任务是按照代码顺序依次执行的任务,而异步任务则是在进入"任务队列"(task queue)中等待执行的任务,例如定时器回调函数、事件回调函数和Promise回调函数等。异步任务又可以分为宏任务和微任务,微任务的执行优先级高于宏任务。当一个宏任务中的所有微任务都执行完毕后,才会执行下一个宏任务。事件循环的工作流程是不断地从任务队列中取出任务并执行,直到队列为空为止

4.事件循环的应用场景

4.1应用场景

01. DOM 事件处理:通过监听 DOM 事件(例如 click、scroll 等),可以使用事件循环来异步更新 UI 或执行其他操作。

02. 定时器:使用 setTimeout() 和 setInterval() 函数可以创建定时器,用于在指定时间间隔之后执行相应的操作。这些操作会被作为异步任务添加到任务队列中等待执行。

03. 网络请求:当 JavaScript 需要发送网络请求时,可以使用 XMLHttpRequest 或 fetch API 发送异步请求,并将响应数据作为异步任务加入到任务队列中等待处理。

04. Promise 和 async/await:Promise 和 async/await 是 JavaScript 中常用的异步编程方式,实际上它们底层都是基于事件循环机制实现的。通过将回调函数封装为 Promise 对象或 async 函数,可以让异步代码更加易读、易维护。

05. Web Workers:Web Workers 可以让 JavaScript 在多线程环境下运行,从而避免阻塞主线程。Web Workers 使用了与事件循环类似的消息队列机制来实现异步通信。

 

4.2.其他:事件是什么?

事件是特定情况下触发的操作。这里的操作是用函数封装起来的,所以,事件就是在特定情况下触发的函数
例如:

  • dom元素相关事件,在用户单击页面上的按钮或页面加载完成时触发;
  • 定时器中,在特定时间间隔后触发其绑定函数;
  • ajax请求中,在请求响应时,才会触发回调函数;
  • promise中,在其内代码有了结果后,再触发 then 函数;

上面的这些情况的回调函数,都是在特定情况下触发的函数,所以都可以称为事件 ;

注意,这里指的是“特定情况”,而不是按代码顺序执行时触发的,也就不是同步触发的,而是异步触发的(函数在特定情况触发的)。所以,事件是异步触发的 。

 

4.3.其他:事件循环是什么?

事物循环,顾名思义,就是事件的循环触发。没错,事件循环的核心就是“事件的循环触发”;
同时事件循环还包括,这些异步操作的触发,回调函数的收集以及回调函数的触发等一系列操作。这些操作其实贯穿整个JS代码的运行
综上所述:

4.4 js是单线程的

JS是单线程的,所以浏览器只会分配一个线程用来解析执行JS代码,同时所有的JS代码也只能在这一个线程中执行。此线程为JS引擎线程。
因为是单线程的,所以代码是同步执行的,也就是按代码顺序执行的,只有前一个任务执行完成,才能执行下一个任务。
那么如果实现在特定情况下触发函数呢?这就需要用于事件循环了

js如何实现异步的===事件循环

1)JS是解释型语言。所以JS是需要在宿主环境中才能运行的。而宿主环境是多线程的。
2)JS是单线程语言。所以宿主环境分配一个线程来解析运行JS代码。
3)宿主环境再利用其他线程来辅助完成其他的一些异步功能。同时创建相关任务队列,用来存储当异步功能完成后要调用的回调函数。
4)最后再循环将这些回调函数放入到JS引擎中的执行栈中,进行调用。

所以:JS的异步功能,是宿主环境的各线程相关联合实现的。而这整个过程可以称为事件循环

 

 

 

 

 

任务队列 & 事件循环

任务队列(消息队列):是一个先进先出的队列,它里面存放着各种任务/消息。

事件循环:主线程不断从事件队列中取出任务 执行事件的过程。

JavaScript事件循环是一种处理异步事件和回调函数的机制,它是JavaScript实现异步编程的核心。它在浏览器或Node.js环境中运行,用于管理任务队列和调用栈,以及在适当的时候执行回调函数。

 

什么是事件循环(Event Loop)机制? 众所周知, Javascript是一门单线程的语言, 单线程即同一时间只能做一件事, 但这并不意味着JavaScript在执行代码的过程中就会一直阻塞,而解决单线程不阻塞的这个机制就叫做事件循环(Event Loop), 也就是同步和异步的概念.在JS中, 所有的任务都可以分为了同步任务异步任务

  • 同步任务: 立即执行的任务, 且只有上一个同步任务执行完毕, 才会执行下一个任务

    按照代码顺序依次执行的任务,同步方法调用一旦开始,调用者必须等到方法调用返回后,才能继续后续的行为。

  • 异步任务: 异步任务指的是,不进入主线程、是在进入"任务队列"(task queue)中等待执行的任务,只有等主线程任务执行完毕,"任务队列"开始通知主线程,请求执行任务,该任务才会进入主线程执行。 即在任务执行时不能立刻得到结果, 而是需要在将来通过一定的手段获取, 则称之为异步任务, 例如网络请求, 定时器, 计时器等

    异步任务需要等待一定的时候才能看到结果

    异步任务任务准备好被主线程处理(即事件被触发,如“定时器到时”,“鼠标点击”,“指定url的网络请求得到响应”),js宿主环境的线程就会将异步任务放入任务队列中。然后,事件循环会在主线程空闲时,从任务队列中取出这个任务,压入js的执行上下文  js主线程执行相应的函数(回调函数)

任务执行流程:

同步任务与异步任务的运行流程图

从上图可以看到, 同步任务和异步任务分别进入不同的执行环境, 同步任务进入主线程, 即主执行栈, 异步任务进入任务队列. 主线程内的任务执行完毕至为空时, 回去任务队列读取对应的任务, 推入主线程执行. 上述过程的不断重复就称之为事件循环(Event Loop)

宏任务和微任务(微 ->宏)

在异步任务中并不像同步任务按顺序执行, 而是再细分为宏任务(macro-task)微任务(micro-task)

每一次Event Loop触发并开始执行异步任务时, 流程如下:

 

 

总结就是:

  • 执行一个宏任务时, 遇到微任务, 会把微任务加入到微任务的事件队列中
  • 当宏任务执行完成后, 再开始依次执行微任务事件队列中的所有微任务

常见的宏任务有:

  • setTimeout/setInterval
  • script(可以理解为外层的同步代码)
  • I/O操作(node.js)

常见的微任务有:

  • Promise的方法
  • Object.observe(已废弃, Proxy对象替代)
  • process.nextTick(node.js)
  • MutaionObserver

 

 

 

 

数据结构与算法:数组 链表 二叉树 图

排序:快排 归并排序

posted @ 2024-04-09 17:47  July_Zheng  阅读(3)  评论(0编辑  收藏  举报