목차
먼저 이벤트 루프가 무엇인지 설명하겠습니다.
웹 프론트엔드 JS 튜토리얼 js 이벤트 루프의 예에 대한 자세한 설명

js 이벤트 루프의 예에 대한 자세한 설명

Jun 26, 2017 am 09:17 AM
javascript 이벤트 주기

이전에 일부 이벤트 루프 블로그를 읽었지만 한동안 읽지 않다가 다 잊어버렸다는 사실을 깨닫고 이를 요약하기 위해 블로그를 작성하기로 결정했습니다!

먼저 이벤트 루프가 무엇인지 설명하겠습니다.

우리가 아는 한, 브라우저의 js는 단일 스레드입니다. 즉, 최대 하나의 코드 세그먼트가 동시에 실행됩니다. 하지만 브라우저는 비동기 요청을 매우 잘 처리할 수 있는데, 그 이유는 무엇일까요? 먼저 사진부터 보겠습니다
js 이벤트 루프의 예에 대한 자세한 설명
위 그림을 보면 js 메인 스레드에 실행 스택이 있고 모든 js 코드가 실행 스택에서 실행되는 것을 볼 수 있습니다. 코드를 실행하는 동안 비동기 코드(예: setTimeout, ajax, promise.then 및 사용자 클릭 등)가 발생하면 브라우저는 이러한 코드를 스레드에 넣습니다(여기에서는 이를 비하인드 코드라고 부릅니다). -scenes 스레드) 대기는 메인 스레드의 실행을 차단하지 않습니다. 백그라운드 스레드의 코드가 준비되면(예: setTimeout 시간이 종료되고 ajax가 실행됨) 요청이 응답되면 스레드가 이를 처리합니다. 콜백 함수는 실행을 기다리는 작업 대기열에 배치됩니다. 메인 스레드가 스택의 모든 코드 실행을 마치면 작업 큐를 확인하여 실행할 작업이 있는지 확인합니다. 실행될 작업이 있으면 작업이 실행 스택에 배치됩니다. 실행. 현재 작업 대기열이 비어 있으면 작업이 도착할 때까지 루프를 계속 기다립니다. 따라서 이를 이벤트 루프라고 합니다.

여기서 질문이 나옵니다. 작업 대기열에 많은 작업이 있는 경우 어떤 작업을 먼저 실행해야 합니까?

실제로 (위 그림과 같이) js에는 두 개의 작업 대기열이 있는데 하나는 Macrotask Queue(Task Queue)라고 하고 다른 하나는 Microtask Queue라고 합니다

    전자는 주로 상대적으로 일부 작업을 수행하는 데 사용됩니다. setTimeout, setInterval, 사용자 상호 작용, UI 렌더링 등이 있습니다.
  • 후자는 주로 비교적 작은 작업을 수행하는 데 사용됩니다. 일반적인 작업에는 Promise, process.nextTick(nodejs)
  • 이 포함됩니다.

  • 그럼 둘의 구체적인 차이점은 무엇인가요? 아니면 두 작업이 동시에 나타나는 경우 어떤 작업을 선택해야 할까요?
실제로 이벤트 루프가 하는 일은 다음과 같습니다.


    매크로태스크 대기열이 비어 있는지 확인하고 비어 있으면 다음 단계로 진행합니다. 3
  1. 매크로태스크 대기열에서 첫 번째 작업을 가져옵니다(대기열에서 가장 긴 작업). 실행 스택(하나만)에서 실행합니다. 실행 후 다음 단계로 이동합니다.
  2. 마이크로태스크를 확인합니다. 큐가 비어 있는지 여부, 비어 있으면 다음 단계로 이동합니다. 그렇지 않으면 1로 점프합니다. 새로운 이벤트 루프)
  3. 마이크로태스크 큐에서 큐의 선두에 있는 태스크(큐에서 가장 긴 시간을 가진 태스크)를 가져와서 이벤트 큐에 입력합니다. 실행 후 3
  4. 으로 점프합니다.
  5. 그 중 코드 실행 중에 추가된 마이크로태스크 작업은 현재 이벤트 루프 주기 내에서 실행되는 반면, 새로 추가된 매크로태스크 작업은 다음 이벤트 루프가 실행될 때까지만 기다릴 수 있습니다(이벤트 루프는 하나만 실행합니다. 매크로태스크)
먼저 코드를 살펴보겠습니다

console.log(1)
setTimeout(function() {
  //settimeout1
  console.log(2)
}, 0);
const intervalId = setInterval(function() {
  //setinterval1
  console.log(3)
}, 0)
setTimeout(function() {
  //settimeout2
  console.log(10)
  new Promise(function(resolve) {
    //promise1
    console.log(11)
    resolve()
  })
  .then(function() {
    console.log(12)
  })
  .then(function() {
    console.log(13)
    clearInterval(intervalId)
  })
}, 0);

//promise2
Promise.resolve()
  .then(function() {
    console.log(7)
  })
  .then(function() {
    console.log(8)
  })
console.log(9)
로그인 후 복사

결과가 어떻게 되어야 한다고 생각하시나요?노드 환경과 크롬 콘솔에서 출력한 결과는 다음과 같습니다.

1
9
7
8
2
3
10
11
12
13
로그인 후 복사

위 예시에서 첫 번째 이벤트 루프 인

:

    console.log(1)이 실행되고, 출력 1
  1. settimeout1이 실행되고, 매크로태스크 대기열에 합류
  2. setinterval1이 실행되고, 매크로태스크 대기열
  3. set에 합류 시간 초과2 실행, 매크로태스크 대기열에 참여
  4. promise2가 실행되고, 두 함수가 마이크로태스크 대기열에 추가됩니다.
  5. console.log(9)가 실행되고, 이벤트 정의에 따라 9
  6. 이 출력됩니다. loop, new가 실행됩니다. 추가된 마이크로태스크 작업은 대기열에 들어간 순서대로 실행됩니다. Console.log(7) 및 console.log(8)이 출력됩니다. 마이크로태스크 대기열은 비어 있습니다. 첫 번째 단계로 돌아가서 다음 이벤트 루프에 들어갑니다. 이때 매크로태스크 대기열은 다음과 같습니다: settimeout1, setinterval1, settimeout2

  7. 두 번째 이벤트 루프:

팀장에서 작업을 수행합니다( settimeout1)을 매크로태스크 대기열에서 실행하면 2가 출력됩니다.
    마이크로태스크 대기열이 비어 있으면 첫 번째 단계로 이동하여 다음 이벤트 루프에 들어갑니다. 이때 매크로태스크 대기열은 setinterval1, settimeout2

  1. 입니다. 세 번째 이벤트 루프:

매크로태스크 대기열에서 팀장(setinterval1)의 작업을 가져와서 실행하고 3을 출력한 다음 새로 생성된 setinterval1을 매크로태스크 대기열에 추가합니다. 첫 번째 단계로 돌아가서 다음 이벤트 루프에 들어갑니다. 이때 매크로태스크 대기열은 다음과 같습니다: settimeout2, setinterval1

  1. 네 번째 이벤트 루프:

팀장에서 작업을 맡습니다. settimeout2)를 매크로태스크 대기열에서 실행하고 10을 출력하고 새 Promise의 함수를 실행합니다(새 Promise의 함수는 비동기 작업이 아닌 동기 작업입니다). 출력 11과 마이크로태스크 대기열에 두 개의 then 함수를 추가합니다

  • 마이크로 태스크 큐에서 큐의 선두에 있는 태스크를 가져와 비어 있을 때까지 실행합니다. 따라서 새로 추가된 두 개의 마이크로태스크 작업이 순서대로 실행되어 출력 12와 13이 되며, 이때 마이크로태스크 대기열과 매크로태스크 대기열은 모두 비어 있습니다. 브라우저는 항상 대기열이 비어 있는지 확인하고 대기합니다. 새로운 작업이 대기열에 추가됩니다.

  • 여기서 첫 번째 루프에서 왜 매크로태스크가 먼저 실행되지 않는지 생각할 수 있습니다. 왜냐하면 프로세스에 따라 먼저 매크로태스크 대기열이 비어 있는지 확인한 다음 마이크로태스크 대기열을 확인해야 하지 않을까요?

    이유: 처음에 js 메인 스레드에서 실행되는 작업은 매크로태스크 작업이므로 이벤트 루프의 프로세스에 따라 이벤트 루프는 메인 스레드의 코드를 실행한 후 하나의 매크로태스크 작업만 실행합니다. , 팀 리더를 데리고 마이크로태스크 대기열로 이동합니다.

    참고:

    마이크로태스크 작업을 실행할 때 마이크로태스크 대기열이 비어 있을 때만 다음 이벤트 루프에 들어갑니다. 따라서 지속적으로 새로운 마이크로태스크 작업을 생성하면 메인 스레드가 마이크로태스크를 실행하고 있습니다. 그리고 매크로태스크 작업을 실행할 수 있는 방법이 없으므로 UI ​​렌더링/IO 작업/ajax 요청을 수행할 수 없으므로 이러한 상황을 피해야 합니다. nodejs의 process.nextick에서 메인 스레드 차단을 방지하기 위해 최대 호출 수를 설정할 수 있습니다.

    이를 통해 타이머 문제라는 새로운 문제를 소개합니다. 타이머는 실제적이고 신뢰할 수 있나요? 예를 들어 setTimeout(task, 100) 명령을 실행하면 100밀리초 후에 정확하게 실행됩니까? 사실 위의 논의를 바탕으로 우리는 이것이 불가능하다는 것을 알 수 있다.

    모두가 그 이유를 알아야 한다고 생각합니다. 왜냐하면 setTimeout(task,100)을 실행한 후 실제로는 작업이 100밀리초 후에 매크로태스크 대기열에 들어가는 것을 보장하기 때문입니다. 그러나 이는 현재 작업이 즉시 실행될 수 있다는 의미는 아닙니다. master 스레드가 시간이 많이 걸리는 작업을 수행하고 있거나 현재 마이크로태스크 대기열에 많은 작업이 있을 수 있으므로 이것이 모두가 setTimeout을 비난하는 이유일 수도 있습니다. ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

    위 내용은 제 개인적인 견해 중 일부일 뿐입니다. 이벤트 루프 및 기타 훌륭한 기사를 참조하세요

    위 내용은 js 이벤트 루프의 예에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    본 웹사이트의 성명
    본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

    핫 AI 도구

    Undresser.AI Undress

    Undresser.AI Undress

    사실적인 누드 사진을 만들기 위한 AI 기반 앱

    AI Clothes Remover

    AI Clothes Remover

    사진에서 옷을 제거하는 온라인 AI 도구입니다.

    Undress AI Tool

    Undress AI Tool

    무료로 이미지를 벗다

    Clothoff.io

    Clothoff.io

    AI 옷 제거제

    AI Hentai Generator

    AI Hentai Generator

    AI Hentai를 무료로 생성하십시오.

    인기 기사

    R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
    3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O. 최고의 그래픽 설정
    3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
    3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
    WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
    4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

    뜨거운 도구

    메모장++7.3.1

    메모장++7.3.1

    사용하기 쉬운 무료 코드 편집기

    SublimeText3 중국어 버전

    SublimeText3 중국어 버전

    중국어 버전, 사용하기 매우 쉽습니다.

    스튜디오 13.0.1 보내기

    스튜디오 13.0.1 보내기

    강력한 PHP 통합 개발 환경

    드림위버 CS6

    드림위버 CS6

    시각적 웹 개발 도구

    SublimeText3 Mac 버전

    SublimeText3 Mac 버전

    신 수준의 코드 편집 소프트웨어(SublimeText3)

    간단한 JavaScript 튜토리얼: HTTP 상태 코드를 얻는 방법 간단한 JavaScript 튜토리얼: HTTP 상태 코드를 얻는 방법 Jan 05, 2024 pm 06:08 PM

    JavaScript 튜토리얼: HTTP 상태 코드를 얻는 방법, 특정 코드 예제가 필요합니다. 서문: 웹 개발에서는 서버와의 데이터 상호 작용이 종종 포함됩니다. 서버와 통신할 때 반환된 HTTP 상태 코드를 가져와서 작업의 성공 여부를 확인하고 다양한 상태 코드에 따라 해당 처리를 수행해야 하는 경우가 많습니다. 이 기사에서는 JavaScript를 사용하여 HTTP 상태 코드를 얻는 방법과 몇 가지 실용적인 코드 예제를 제공합니다. XMLHttpRequest 사용

    jQuery에서 선택 요소의 변경 이벤트 바인딩을 구현하는 방법 jQuery에서 선택 요소의 변경 이벤트 바인딩을 구현하는 방법 Feb 23, 2024 pm 01:12 PM

    jQuery는 DOM 조작, 이벤트 처리, 애니메이션 효과 등을 단순화하는 데 사용할 수 있는 인기 있는 JavaScript 라이브러리입니다. 웹 개발에서 우리는 선택 요소에 대한 이벤트 바인딩을 변경해야 하는 상황에 자주 직면합니다. 이 기사에서는 jQuery를 사용하여 선택 요소 변경 이벤트를 바인딩하는 방법을 소개하고 특정 코드 예제를 제공합니다. 먼저 라벨을 사용하여 옵션이 포함된 드롭다운 메뉴를 만들어야 합니다.

    람다 표현식이 루프에서 벗어남 람다 표현식이 루프에서 벗어남 Feb 20, 2024 am 08:47 AM

    람다 표현식은 루프에서 벗어나기 때문에 특정 코드 예제가 필요합니다. 프로그래밍에서 루프 구조는 자주 사용되는 중요한 구문입니다. 그러나 특정 상황에서는 현재 루프 반복을 종료하는 대신 루프 본문 내에서 특정 조건이 충족될 때 전체 루프를 중단하고 싶을 수도 있습니다. 이때 람다 표현식의 특징은 루프에서 벗어나는 목표를 달성하는 데 도움이 될 수 있습니다. 람다 표현식은 내부적으로 간단한 함수 논리를 정의할 수 있는 익명 함수를 선언하는 방법입니다. 일반적인 함수 선언과는 다릅니다.

    JavaScript에서 HTTP 상태 코드를 쉽게 얻는 방법 JavaScript에서 HTTP 상태 코드를 쉽게 얻는 방법 Jan 05, 2024 pm 01:37 PM

    JavaScript에서 HTTP 상태 코드를 얻는 방법 소개: 프런트 엔드 개발에서 우리는 종종 백엔드 인터페이스와의 상호 작용을 처리해야 하며 HTTP 상태 코드는 매우 중요한 부분입니다. HTTP 상태 코드를 이해하고 얻는 것은 인터페이스에서 반환된 데이터를 더 잘 처리하는 데 도움이 됩니다. 이 기사에서는 JavaScript를 사용하여 HTTP 상태 코드를 얻는 방법을 소개하고 구체적인 코드 예제를 제공합니다. 1. HTTP 상태 코드란 무엇입니까? HTTP 상태 코드는 브라우저가 서버에 요청을 시작할 때 서비스가

    PHP는 배열의 모든 값을 반환하여 배열을 형성합니다. PHP는 배열의 모든 값을 반환하여 배열을 형성합니다. Mar 21, 2024 am 09:06 AM

    이 기사에서는 PHP가 배열의 모든 값을 반환하여 배열을 형성하는 방법을 자세히 설명합니다. 편집자는 이것이 매우 실용적이라고 생각하므로 이 기사를 읽고 뭔가를 얻을 수 있기를 바랍니다. . array_values() 함수 사용하기 array_values() 함수는 배열에 있는 모든 값의 배열을 반환합니다. 원래 배열의 키는 유지되지 않습니다. $array=["foo"=>"bar","baz"=>"qux"];$values=array_values($array);//$values는 ["bar","qux"]를 사용하여 루프는 루프를 사용하여 배열의 모든 값을 수동으로 가져오고 새 값에 추가할 수 있습니다.

    PHP를 사용하여 이벤트 기반 애플리케이션을 구축하는 방법 PHP를 사용하여 이벤트 기반 애플리케이션을 구축하는 방법 May 04, 2024 pm 02:24 PM

    PHP에서 이벤트 기반 애플리케이션을 구축하는 방법에는 EventSourceAPI를 사용하여 이벤트 소스를 생성하고 EventSource 객체를 사용하여 클라이언트 측에서 이벤트를 수신하는 방법이 포함됩니다. SSE(Server Sent Events)를 사용하여 이벤트를 보내고 XMLHttpRequest 객체를 사용하여 클라이언트 측에서 이벤트를 수신합니다. 실제적인 예는 EventSource를 사용하여 전자 상거래 웹 사이트에서 실시간으로 재고 수를 업데이트하는 것입니다. 이는 재고를 무작위로 변경하고 업데이트를 보내는 방식으로 서버 측에서 이루어지며, 클라이언트는 EventSource를 통해 재고 업데이트를 수신하고 이를 표시합니다. 실시간.

    Java Iterator와 Iterable: 우아한 코드 작성을 위한 단계 Java Iterator와 Iterable: 우아한 코드 작성을 위한 단계 Feb 19, 2024 pm 02:54 PM

    Iterator 인터페이스 Iterator 인터페이스는 컬렉션을 순회하는 데 사용되는 인터페이스입니다. hasNext(), next() 및 Remove()를 포함한 여러 메소드를 제공합니다. hasNext() 메서드는 컬렉션에 다음 요소가 있는지 여부를 나타내는 부울 값을 반환합니다. next() 메서드는 컬렉션의 다음 요소를 반환하고 컬렉션에서 제거합니다. Remove() 메서드는 컬렉션에서 현재 요소를 제거합니다. 다음 코드 예제에서는 Iterator 인터페이스를 사용하여 컬렉션을 반복하는 방법을 보여줍니다. Listnames=Arrays.asList("John","Mary","Bob");Iterator

    Java 함수의 재귀 호출에 대한 대안은 무엇입니까? Java 함수의 재귀 호출에 대한 대안은 무엇입니까? May 05, 2024 am 10:42 AM

    Java 함수의 재귀 호출을 반복으로 대체 Java에서 재귀는 다양한 문제를 해결하는 데 사용되는 강력한 도구입니다. 그러나 어떤 경우에는 반복을 사용하는 것이 더 효율적이고 스택 오버플로가 발생할 가능성이 적기 때문에 더 나은 옵션일 수 있습니다. 반복의 장점은 다음과 같습니다. 각 재귀 호출에 대해 새 스택 프레임을 생성할 필요가 없으므로 더 효율적입니다. 스택 공간 사용량이 제한되어 있기 때문에 스택 오버플로가 발생할 가능성이 적습니다. 재귀 호출의 대안인 반복 메소드: Java에는 재귀 함수를 반복 함수로 변환하는 여러 메소드가 있습니다. 1. 스택 사용 스택을 사용하는 것은 재귀 함수를 반복 함수로 변환하는 가장 쉬운 방법입니다. 스택은 함수 호출 스택과 유사한 LIFO(후입선출) 데이터 구조입니다. 공공 인파

    See all articles