JS 함수의 setTimeout에 대한 자세한 소개

亚连
풀어 주다: 2018-06-19 17:29:29
원래의
1338명이 탐색했습니다.

이 글은 주로 setTimeout의 js 함수 실행 과정을 소개하는데, 필요하신 분들은 참고하시면 됩니다

솔직히 이 글을 쓰면서 타격을 받아서 좀 우울한 기분이 들었습니다. 저는 장난을 좋아해서 우연히 이 "간단한" 기능을 봤습니다:

for (var i = 0; i < 5; i++) {
      setTimeout(function () {
        console.log(i)
      }, i * 1000);
    }
    console.log(i);
로그인 후 복사

뭐? 이것은 오래전에 5를 인쇄한 다음 5를 인쇄하고 6개의 5가 인쇄될 때까지 매초마다 5를 인쇄하는 구현 방법이 아닌가? 그렇다면 질문이 생깁니다. 0,1,2,3,4,5를 순서대로 인쇄하려면 어떻게 해야 합니까? 사실 이전에는 두 가지 방법이 있다는 것을 알고 있었습니다. 하나는 다음과 같습니다:

function log(i){
setTimeout(function(){
console.log(i)
},i*1000)
};
for (var i = 0; i < 5; i++) {
      log(i) ;
    }
    console.log(i);
로그인 후 복사

the other 바로 이것입니다:

for(var i=0;i<5;i++){
(function(e){
setTimeout(function(){
console.log(e)
},i*1000);
})(i);
};
console.log(i);
로그인 후 복사

농담을 두려워하지 마세요. 전에는 이 두 기능이 실제로 어떤 용도로 사용되었는지 이해하지 못했기 때문에 억지로 기억하고 수정했지만 그렇지 않습니다. 지금은 일을 하지 않아요. 강박 장애가 있어요! 그래서 천천히 분석해 보니 위 코드는

i=0; 조건이 충족되면

setTimeout(function(){
console.log(i)
},0*1000);
로그인 후 복사

i=2; ; 조건이 충족되면 ;

setTimeout(function(){
console.log(i)
},1*1000);
로그인 후 복사

i=4; 조건이 충족되지 않으면 for 루프 다음에 console.log(i)를 실행하고 5를 인쇄합니다.

정말 흥미롭습니다. 왜 setTimeout 내부의 console.log가 for 루프 외부에서 실행됩니까? => "queue"라는 단어를 깨닫기 전까지 대기열은 매크로 작업 대기열(Macro Task)과 마이크로 작업 대기열(Micro Task)로 구분됩니다. javascript:

macro-task에는 script(전체 코드) , setTimeout, setInterval이 포함됩니다. , setImmediate, I/O, UI 렌더링.

마이크로 작업에는 process.nextTick, Promises, Object.observe, MutationObserver

위 함수의 setTimeout이 매크로 작업입니다.

js에서 이벤트 루프의 순서는 스크립트에서 시작하는 첫 번째 루프입니다. 그런 다음 전역 컨텍스트에 함수 호출 스택을 입력하고 매크로 작업이 발생하면 이를 처리하는 모듈에 전달합니다. 처리 후 콜백 함수를 매크로 작업 대기열에 넣습니다. 콜백 함수를 대기열의 마이크로 작업에 넣습니다. 함수 호출 스택이 지워지고 전역 실행 컨텍스트만 남을 때까지 모든 마이크로 작업이 실행되기 시작합니다. 실행 가능한 모든 마이크로 작업이 실행된 후. 루프는 다시 매크로 태스크의 태스크 큐를 실행하고, 실행 후 마이크로 태스크를 모두 실행하는 방식으로 루프가 계속됩니다.

이것이 setTimeout 내부의 console.log가 for 루프 외부의 console.log 이후에 실행되는 이유입니다. 함수 실행 컨텍스트에서 seiTimeout 함수는 매크로 작업을 처리하기 위해 대기열에 배치되므로 루프는 setTimeout의 함수는 실행되지 않지만 큐의 함수가 실행되기 전에 전체 코드(큐가 아닌)가 실행될 때까지 기다립니다. 이를 작성하는 것은 약간 혼란스러울 수 있습니다. 사실 저도 약간 혼란스럽습니다. 하하하! !

더 깊은 이해를 위해 Promise를 추가해 볼 수도 있으니 다음과 같습니다.

setTimeout(function(){
console.log(i)
},2*1000);
로그인 후 복사

Explain it =>

1 먼저 스크립트 작업 소스가 먼저 실행되고 전역 컨텍스트가 푸시됩니다. 스택에.

2. 스크립트 작업 소스 코드가 실행 중에 setTimeout을 만나면 매크로 작업으로 콜백 함수를 자체 대기열에 넣습니다.

3. 스크립트 작업 소스의 코드는 실행 중에 Promise 인스턴스를 발견합니다. Promise 생성자의 첫 번째 매개변수는 현재 작업을 직접 실행하면 대기열에 넣지 않으므로 이때는 1이 출력됩니다.

4. for 루프에서 해결 함수를 만나면 해당 함수가 스택에 푸시된 후 튀어나옵니다. 이때 Promise 상태는 Fulfilled가 됩니다. 그런 다음 코드가 실행되어 console.log(2)를 발견하고 2를 출력합니다.

5. 그런 다음 실행하면 코드가 then 메서드를 만나고 해당 콜백 함수가 마이크로 태스크로 스택에 푸시되어 Promise의 작업 대기열에 들어갑니다. 이때 Promise의 함수 콜백 함수도 비슷합니다. 즉, 함수 컨텍스트, 즉 스크립트의 대기열이 아닌 모든 코드가 실행되고 마이크로 작업 대기열이 처리될 때까지 해당 작업 대기열에 배치됩니다. 매크로 작업 대기열 이전에

전체 순서는 다음과 같습니다: 컨텍스트 비 대기열 코드 > 마이크로 작업 대기열 콜백 함수 코드 > 매크로 작업 대기열 콜백 함수 코드

6 그런 다음 코드가 실행되고 console.log(3)이 됩니다. 이때 발생하여 3이 출력됩니다.

7. 3을 출력한 후 첫 번째 매크로태스크 스크립트의 코드가 실행됩니다. 이때 대기열에 있는 모든 마이크로태스크가 실행되기 시작합니다. then의 콜백 함수가 스택에 푸시된 후 팝아웃됩니다. 이때 5

8이 출력됩니다. 이때 모든 마이크로 작업이 완료되고 첫 번째 사이클이 종료됩니다. 두 번째 루프는 setTimeout의 작업 대기열에서 시작됩니다. setTimeout의 콜백 함수가 스택에 푸시된 후 이때 4가 출력됩니다.

마지막으로 이해를 돕기 위해 또 다른 코드가 있습니다:

setTimeout(function(){
console.log(i)
},3*1000);
로그인 후 복사

실행 결과가 다음과 같은 경우: golb1=>glob1_promise=>glob1_then=>timeout1=>timeout1_promise=>timeout1_then=> prp_timeout=>time_timeout=>timeout1_timeout1,

아마도 비동기 대기열이 소개될 것 같아요! ~~위의 코드는 약간 지저분해 보입니다. asyns를 사용하고 변환을 기다리는 것이 더 나을 수도 있지만 이것은 setTimeout에서 얻은 통찰력입니다.

위는 내가 모든 사람을 위해 컴파일한 것입니다. 앞으로는 더 나아지세요 다들 도움이 많이 되네요.

관련 기사:

Three.js를 사용하여 WeChat 점프 게임을 구현하는 방법

NODEJS에서 http 구현에 대한 자세한 소개

nodejs를 사용하여 채팅 기능을 구현하는 방법

JavaScript의 고급 기능 사용 방법

Angular5를 사용하여 서버 측 렌더링 실습 구현

vuex에서 유휴 상태를 재설정하는 방법

위 내용은 JS 함수의 setTimeout에 대한 자세한 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿