setTimeout 에 관 한 면접 문제

3397 단어
인터넷 의 전단 면접 문제 에서 setTimeout 에 관 한 문 제 를 자주 볼 수 있 습 니 다. 이 문 제 는 자주 쓰 입 니 다. 한 문 제 는 자바 script 의 역할 영역, 폐쇄, 사건 순환 에 관 한 지식 점 을 포함 하고 이런 지식 점 을 이해 하 는 것 이 전단 개발 자 에 게 자바 script 언어 차원 에 대한 이해 정도 의 중요성 을 설명 합 니 다.자신의 이해 에 따라 일부 자 료 를 참고 하여 이 문 제 를 풀 어 보 는 동시에 지식 도 공 고 히 한다.여기 서 먼저 이 고전적 인 문 제 를 풀 어 보 겠 습 니 다.
//             ?
for(var i = 0; i <= 5; i++) {
    setTimeout(function() {
        console.log(i);
    },1000)
}

기본적으로 코드 의 출력 을 예측 할 수 있 습 니 다.
하지만 실제 답 은 log 이후 다섯 개의 숫자 6 을 순환 출력 했다!!
이 어 면접 관 이 코드 를 바 꿔 달라 고 할 수도 있 습 니 다. 결 과 는 1 초 간격 으로 숫자 를 출력 하 기 를 바 랍 니 다. 즉,:
  1     1,  2    2,  3    3....

지식 점 에 대하 여
1. 역할 영역
에서 비 유 를 인용 하면 역할 도 메 인 체인 을 고 층 건물 로 상상 할 수 있 고 1 층 은 현재 집행 역할 도 메 인 을 대표 하 며 건물의 꼭대기 층 은 전체 역할 도 메 인 을 대표 한다.우 리 는 변 수 를 찾 을 때 먼저 현재 층 에서 찾 습 니 다. 만약 에 찾 지 못 하면 엘리베이터 를 타고 위층 으로 갑 니 다. 만약 에 찾 지 못 하면 계속 위로 찾 습 니 다. 이런 식 으로 유추 합 니 다.맨 위 에 도착 하면 (전역 역할 영역) 필요 한 변 수 를 찾 았 을 수도 있 고 찾 지 못 했 을 수도 있 지만 아무리 찾 아 도 과정 이 멈 출 것 입 니 다.
2. 폐쇄
나 는 홍 보 서 (JavaScript 고급 프로 그래 밍) 의 묘사 가 매우 이해 하기 쉽다 고 생각한다.패 킷 을 닫 는 것 은 다른 함수 역할 영역 에 접근 할 수 있 는 변수의 함수 입 니 다.패 킷 을 닫 는 일반적인 방식 은 한 함수 내부 에 다른 함 수 를 만 드 는 것 입 니 다.예: A 함수 에서 B 함 수 를 정의 하고 B 함 수 를 되 돌려 주 었 습 니 다. 그러면 B 함수 가 어디서 호출 되 든 어떻게 호출 되 든 A 함수 의 역할 영역 을 유지 합 니 다.
3. 이벤트 순환
이 개념 은 비교적 많은 개념 과 관련 되 고 편폭 이 비교적 크 며 다음 편 은 따로 뽑 아서 쓸 것 이다.완 일 봉 선생님 의 해설 을 참고 할 수 있 습 니 다.http://www.ruanyifeng.com/blog/2014/10/event-loop.html 여기 서 우 리 는 사건 순환 / 미 션 대열 의 지식 을 알 았 다 고 생각 하고 말 합 니 다.
코드 실행 순서 분석
이 코드 의 실행 순 서 를 되 돌아 보 세 요. 우선 for 순환 으로 실 행 됩 니 다. js 엔진 에서 setTimeout 을 읽 을 때 setTimeout 은 즉시 실 행 된 것 이 아니 기 때문에 그들의 리 셋 은 push 에 의 해 매크로 작업 대기 열 에 있 는 리 셋 함 수 를 되 돌 릴 때 변 수 는 이미 6 이 되 었 습 니 다.원인 을 알 고 우 리 는 문 제 를 해결 하 는 데 착수 했다.여기 서 우 리 는 setTimeout 에 패 킷 을 닫 는 환경 을 만들어 서 리 셋 함수 가 순환 중인 변수 i 를 순조롭게 가 져 오 면 문 제 를 해결 할 수 있 도록 해 야 합 니 다.
여기 서 4 가지 방법 을 정리 하 였 습 니 다. 자세히 살 펴 보면 익숙 한 표기 법 이 될 것 입 니 다. (1) IIFE (즉시 실행 되 는 익명 함수) 를 사용 합 니 다.
//  1     1,2,3,4, 5
for(var i = 1; i <= 5; i++) {
    (function(i){
        setTimeout(function() {
            console.log(i);
        }, i*1000)
    })(i);
}

(2) ES6 문법 중의 let 를 사용 하여 변수 i es6 중의 let 성명 변 수 는 블록 급 역할 도 메 인 을 가지 기 때문에 우 리 는 대담 하 게 사용 할 수 있다.
for(let i = 1;i <=5; i++) {
    setTimeout(function() {
        console.log(i);
    },i*1000)
}

(3) bid 방법 사용
for(var i = 1; i <= 5; i++) {
     setTimeout(function(i) {
        console.log(i);
    }.bind(null, i),i*1000)
}

(4) setTimeout 의 세 번 째 매개 변 수 를 이용 합 니 다!!
for(var i = 1; i<= 5;i++) {
    setTimeout(function time(i) {
        console.log(i);
    },i*1000,i)
 }

메모: setTineout 의 세 번 째 매개 변수 와 이후 매개 변 수 는 모두 리 셋 함수 의 매개 변수 로 사용 할 수 있 습 니 다.
setTimeout 에 대한 지연 매개 변수
setTimeout(function() {
  console.log('     ');
},3000)

우 리 는 일반적으로 코드 가 3 초 후에 실행 된다 고 말 하 는데, 이러한 견 해 는 엄밀 하지 않다.
정확 한 설명 은 3 초 후 setTimeout 의 함수 가 이벤트 quue 로 밀 려 들 고 이벤트 quue 의 임 무 는 메 인 라인 이 비어 있어 야 수행 할 수 있 습 니 다.만약 에 메 인 스 레 드 에 많은 작업 이 실행 되 고 3 초 를 초과 하면 이 함 수 는 10 초 후에 만 실행 할 수 있 습 니 다.
  • 또한 브 라 우 저의 실행 일 치 를 확보 하기 위해 HTML 5 규범 에 규정된 최소 지연 은 4ms
  • 입 니 다.
    OK, 이것 이 바로 제 가 알 고 있 는 setTimeout 에 관 한 모든 점 입 니 다. javascript 의 지식 은 흩 어 지고 복잡 하 며 서로 격려 합 니 다 ~

    좋은 웹페이지 즐겨찾기