Uma compreensão completa do loop de eventos do loop de eventos do navegador

prefácio

  O event loop do navegador e o event loop do Node são os pontos de conhecimento que todo engenheiro de front-end deve dominar. Geralmente lidamos mais com o navegador. Este artigo apresenta primeiro o loop de eventos do navegador. O autor analisa o problema a partir das seguintes perspectivas e leva ao que é o loop de eventos?

  1. Você sabe o que é um processo em um sistema operacional? O que é um fio?
  2. O JS é single-thread ou multi-thread?
  3. O navegador é multiprocesso ou de processo único? Por quê?
  4. Se o JS for single threaded, como ele alcança o processamento assíncrono?
  5. Traga o loop de eventos

1. O que é um processo? O que é um fio?

  Em primeiro lugar, eu recomendo um livro "Sistema Operacional Moderno" para você.Se você realmente entender a essência do sistema operacional, muitos problemas de desenvolvimento de repente se tornarão claros. 在操作系统中无论是运行系统中的什么应用,最终都是会编译成二进制交CPU给执行。
  Em nosso uso diário de computadores, podemos ouvir música, escrever código e blogar ao mesmo tempo. Nesses aplicativos, um processo ou vários processos serão abertos no sistema operacional e os processos abertos por diferentes aplicativos são diferentes. Para a compreensão de todos, é comparado que apenas um processo será aberto em um aplicativo e vários threads serão abertos em um processo. Se houver apenas um thread, nós o chamamos de thread principal. 结论:一个进程当中包含多个线程或只有一个主线程。
  Desenhe uma imagem para que todos entendam a relação entre processos e threads de forma mais intuitiva

1.jpg   Nesta imagem, a camada mais externa é equivalente ao sistema operacional. Vamos baixar muitos aplicativos no sistema operacional. Quando executamos VsCode, Netease Cloud Music, uma carta, etc.,
  eles iniciarão um processo ou vários processos. (Isso está relacionado ao próprio aplicativo), e um processo contém vários threads. Se houver apenas um thread, ele é chamado de thread principal.
  Se você ainda não sabe muito sobre processos e threads ao ver isso, permita-me descrever a relação entre eles com um exemplo fácil de entender.
  操作系统就跟工厂一样,一个工厂会包含多个车间,其中多个车间就好比是我们的应用程序有多个进程,车间里面有工人在工作,就相当于是线程的概念。

2. O JS é single-thread ou multi-thread?

  答案:JS是单线程。Se você se aprofundar, por que é single threaded?
  Na verdade, isso está relacionado ao seu uso, pois JS é uma linguagem de script de navegador, e seu principal objetivo é realizar operações do usuário e manipular o DOM, portanto, só pode ser single-thread, caso contrário, trará muitos problemas complexos de sincronização.

3. O navegador é multiprocesso ou de processo único

  答案:浏览器是多进程的。为什么说是多进程的? 你说是就是吗? 凭什么呢?
  当我们浏览网页的时候,有的时候是不是会遇到浏览器卡死的情况。如果我们开了多个会话,就假如我们一边刷力扣,一边开发程序,写循环的时候,写了一个死循环,导致了我们开发的这个会话的崩溃,如果浏览器是单进程的情况下,力扣这个时候也会崩溃。
  当然浏览器肯定不会允许这样的事情发生,它就是多进程的,多个会话互相不影响,你要崩溃你崩溃去,跟我可没关系,哈哈哈哈哈。

4.JS实现异步处理

  首先当您看到了这里,其实你们离成功只有一步之遥了,跟着我继续探讨下去,把Event Loop一点一点捣碎了,喂进你们的嘴里。

  我们先来看一段同步的JS代码

const foo = 'foo'

function bar() {
  console.log('bar')
}

console.log(foo) //foo
bar() //bar

复制代码

  JS的代码执行顺序是从上至下进行的,所以答案如注释所示,我们是毫无疑问的

  现在玩点花样,来一点同步和异步代码给大家看看

const foo = 'foo'

function bar() {
  console.log('bar')
}

queueMicrotask(() => {
  console.log('microtask')
})

console.log(foo) 

setTimeout(() => {
  console.log('setTimeout')
},1000)

bar()

//主线程: foo bar
//微任务队列:microtask
//宏任务队列:setTimeout
//执行顺序: foo bar microtask setTimeout(1s过后)

复制代码

  现在穿插了异步的代码,如果把上面从上至下运行代码的结论用到异步,肯定是错误的! 正确的执行顺序的答案,大家可以先看一下,可能对异步不太了解的人会产生疑惑,不要慌,我们一点一点来看,引出下面的事件循环。

5.事件循环

  首先我们又回到 JS 代码是单线程开始讲起,当我们编写的同步的代码的时候,代码的执行顺序是从上至下的,但是当有异步操作或者一些耗时操作的时候,如果还是按照之前的结论从上至下的话,那么一定会堵塞我们主线程的代码 也就是 main script中的代码,这样在js当中肯定是不被允许的。假如我有耗时操作(setTimeout)或者网络请求(ajax),延迟了5s才执行,那我后面的代码都堵塞了。
用文字的形式,还是有点抽象,我们直接上图,到底是一个怎么样的机制,完美解决这一问题。

2.jpg   Descreva brevemente esta imagem: Primeiro, o código js executa o código da thread principal, ou seja, o código síncrono. De cima para baixo, quando o código assíncrono é encontrado, ele é entregue ao navegador, e o navegador abre um thread especial, em que o thread do navegador Manter essas duas filas, 一个微任务队列,一个宏任务队列.
  注意:每一次执行宏任务之前,都是要确保我微任务的队列是空的,也就是说从代码执行的顺序来说微任务优先于宏任务。
  No entanto, há uma situação de corte de fila, ou seja, quando eu termino de executar a micro-tarefa e começo a executar a macro-tarefa (existem várias macro-tarefas), quando o código na fila da macro- fila de tarefas é executada, há outro código de microtarefa na fila de macrotarefas. , e coloque a microtarefa na fila de microtarefas.
  Preste atenção especial neste momento! ! ! A rigor, ela é seguida pela macro tarefa que é compilada primeiro, mas, neste momento, há uma fila de microtarefas na microtarefa que é executada antes da execução da tarefa, em vez de ser executada diretamente. Esses códigos assíncronos são entregues ao js para execução 这样三者形成了一个闭环,我们称之为事件循环.

Acho que você gosta

Origin juejin.im/post/7079092748929728548
Recomendado
Clasificación