programing

setTimeout이 내 루프를 취소하지 않는 이유는 무엇입니까?

nasanasas 2020. 10. 19. 08:09
반응형

setTimeout이 내 루프를 취소하지 않는 이유는 무엇입니까?


JavaScript while문 (Chrome 콘솔에 있음)이 몇 밀리 초 안에 변수를 증가 시킬 수 있는지 궁금해서이 코드를 콘솔에 직접 작성했습니다.

var run = true, i = 0;
setTimeout(function(){ run = false; }, 1);
while(run){ i++; }

문제는 그것이 영원히 실행된다는 것입니다.
왜 이런 일이 발생하며 어떻게 해결할 수 있습니까?


이것은 JavaScript 1 의 1- 스레드 특성으로 돌아옵니다 . 무슨 일이 일어나는지 거의 다음과 같습니다.

  1. 변수가 할당됩니다.
  2. 을 설정하기 위해 기능을 예약합니다 run = false. 이것은 현재 기능이 실행 된 후에 실행되도록 예약됩니다 (또는 현재 활성화 된 다른 기능).
  3. 무한 루프가 있고 현재 함수 안에 머물러 있습니다.
  4. 무한 루프 후에 ( 절대 ) setTimeout()콜백이 실행되고 run=false.

보시다시피 setTimeout()여기 에서는 접근 방식이 작동하지 않습니다. while상태 의 시간을 확인하여 문제를 해결할 수 있지만 이것은 실제 측정을 변경합니다.

1 적어도 더 실용적인 목적을 위해 단일 스레드로 볼 수 있습니다. 실제로 소위 "이벤트 루프"가 있습니다. 이 루프에서 모든 함수는 실행될 때까지 대기열에 추가됩니다. 새 함수를 큐에 넣으면 해당 큐 내의 각 위치에 놓입니다. 현재 함수가 완료된 엔진은 대기열에서 다음 함수를 가져옵니다 (예 : 시작된 타이밍과 관련하여 setTimeout()이를 실행합니다.
결과적으로 매 시점마다 하나의 함수 만 실행되므로 실행이 예쁘게됩니다.) 많은 단일 스레드. 아래 링크에서 논의되는 이벤트에 대한 몇 가지 예외가 있습니다.


참고로 :


JavaScript는 단일 스레드이므로 루프에있는 동안 다른 것은 실행되지 않습니다.


속도를 계산하기 위해 시간을 계속 검색하지 않고도 Chrome의 진정한 속도를 유지하려면 다음 JS 코드를 시도해 볼 수 있습니다.

var start = new Date().getTime()
var i = 0
while(i<1000000)
{
    i++
}
var end = new Date().getTime()
var delta = end-start
var speed = i/delta
console.log(speed + " loops per millisecond")

Javascript는 단일 스레드이므로 한 번에 하나의 명령 만 순차적으로 실행합니다.

다른 많은 언어 및 라이브러리에서와 같이 이벤트 시스템은 이벤트 루프에 의해 처리됩니다. 이벤트 루프는 기본적으로 루프이며, 각 반복에서 큐의 메시지를 확인하고 이벤트를 전달합니다.

자바 스크립트 (이 패턴을 구현하는 다른 언어에서와 같이)에서 이벤트 루프는 스택이 비어있을 때, 즉 모든 함수가 프로그램 코드의 끝에서 반환을 가질 때 호출됩니다.

"실제"프로그램은 뒤에서 다음과 같이 보입니다.

var run = true, i = 0;
setTimeout(function(){ run = false; }, 1);
while(run){ i++; }

while(true) {
/*
 * check for new messages in the queue and dispatch
 * events if there are some
 */
  processEvents();
}

따라서 시간 초과가 끝났다는 시계의 메시지는 처리되지 않습니다.

이벤트 루프에 대한 추가 정보 : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/EventLoop


물론 좀 더 복잡합니다. 여기에서 예제를 확인하십시오. JavaScript는 단일 스레드가 보장됩니까? ( tl; dr : 일부 브라우저 엔진에서 일부 외부 이벤트는 이벤트 루프에 종속되지 않고 발생시 즉시 실행되어 현재 작업을 선점합니다. 그러나 이것은 큐에 메시지를 추가하는 setTimeout의 경우가 아닙니다. 즉시 발사하지 않습니다.)


While 루프는 setTimeout에 액세스하지 않습니다. true로 실행되는 코드가 있으면 절대로 false가되지 않습니다.


JavaScript has single thread and has single-threaded anywhere.

I think this question in good: Is JavaScript guaranteed to be single-threaded?

When your code is in loop other ocde not execute and block.

참고URL : https://stackoverflow.com/questions/21656766/why-isnt-settimeout-cancelling-my-loop

반응형