프로그래밍 언어/HTML,CSS,JS

JavaScript는 단일 스레드가 보장되는걸까?

Rateye 2021. 6. 28. 10:11
728x90
반응형
질문 : JavaScript는 단일 스레드가 보장됩니까?

JavaScript는 모든 최신 브라우저 구현에서 단일 스레드로 알려져 있지만 표준에 지정되어 있습니까 아니면 전통에 의해서만 지정됩니까? JavaScript가 항상 단일 스레드라고 가정하는 것이 완전히 안전합니까?

답변

그건 좋은 질문이야. “예”라고 말하고 싶습니다. 난 못해.

JavaScript는 일반적으로 scripts (*)에 단일 실행 스레드가 표시되는 것으로 간주되므로 인라인 스크립트, 이벤트 리스너 또는 시간 제한이 입력되면 블록 또는 함수의 끝에서 돌아올 때까지 완전히 제어 할 수 있습니다.

(* : 브라우저가 실제로 하나의 OS 스레드를 사용하여 JS 엔진을 구현하는지 또는 다른 제한된 실행 스레드가 WebWorkers에 의해 도입되는지 여부에 대한 질문을 무시합니다.)

그러나 실제로 이것은 은밀하고 불쾌한 방식으로 사실이 아닙니다.

가장 일반적인 경우는 즉각적인 사건입니다. 코드가 이러한 문제를 일으키는 작업을 수행하면 브라우저가 즉시 실행합니다.

 
var l= document.getElementById('log');
var i= document.getElementById('inp');
i.onblur= function() {
    l.value+= 'blur\n';
};
setTimeout(function() {
    l.value+= 'log in\n';
    l.focus();
    l.value+= 'log out\n';
}, 100);
i.focus();
<textarea id="log" rows="20" cols="40"></textarea>
<input id="inp">
 

IE를 제외한 모든 곳에서 log in, blur, log out focus() 직접 호출했기 때문에 발생하는 것이 아니라 alert() 를 호출했거나 팝업 창을 열었 기 때문에 발생하거나 포커스를 이동하는 다른 모든 이벤트가 발생할 수 있습니다.

이로 인해 다른 이벤트가 발생할 수도 있습니다. 예를 들어 i.onchange focus() 호출이 포커스를 해제하기 전에 입력에 무언가를 입력하고 로그 순서는 log in, change, blur, log out 하는 Opera를 제외하고 log in, blur, log out, change 및 IE가 log in, change, log out, blur 됩니다.

마찬가지로 제공하는 요소에서 click() onclick 핸들러를 호출합니다 (적어도 일관성이 있습니다!).

on... 이벤트 처리기 속성을 사용하고 addEventListenerattachEvent 에서도 동일하게 발생합니다.)

또한 코드가 스레드되는 동안 이벤트를 유발할 수있는 작업을 수행하지 않았 음에도 불구하고 이벤트가 발생할 수있는 상황이 많이 있습니다. 예 :

 
var l= document.getElementById('log');
document.getElementById('act').onclick= function() {
    l.value+= 'alert in\n';
    alert('alert!');
    l.value+= 'alert out\n';
};
window.onresize= function() {
    l.value+= 'resize\n';
};
<textarea id="log" rows="20" cols="40"></textarea>
<button id="act">alert</button>
 

alert 를 누르면 모달 대화 상자가 나타납니다. 대화를 닫을 때까지 더 이상 스크립트가 실행되지 않습니다. 아니. 기본 창 크기를 조정하면 텍스트 영역에서 alert in, resize, alert out

모달 대화 상자가있는 동안 창 크기를 조정하는 것이 불가능하다고 생각할 수도 있지만 그렇지 않습니다. Linux에서는 원하는만큼 창 크기를 조정할 수 있습니다. Windows에서는 그렇게 쉽지는 않지만 화면 해상도를 더 큰 크기에서 창이 맞지 않는 작은 크기로 변경하여 크기를 조정할 수 있습니다.

스크립트가 스레드되어 있기 때문에 사용자가 브라우저와 활발하게 상호 작용하지 않을 때 실행될 수 resize scroll 과 비슷한 몇 가지) 뿐이라고 생각할 수 있습니다. 그리고 단일 창문의 경우 귀하가 옳을 수 있습니다. 그러나 크로스 윈도우 스크립팅을 수행하자마자 모든 것이 냄비에 들어갑니다. 모든 창 / 탭 / 프레임 중 하나가 사용 중일 때 모든 창 / 탭 / 프레임을 차단하는 Safari 이외의 모든 브라우저의 경우 별도의 실행 스레드에서 실행되고 관련 이벤트 처리기가 다른 문서의 코드에서 문서와 상호 작용할 수 있습니다. 불.

스크립트가 여전히 스레드되는 동안 생성 될 수있는 이벤트가 발생할 수있는 위치 :

  • Opera를 제외한 모든 브라우저에서 모달 팝업 ( alert , confirm , prompt
  • 지원하는 브라우저에서 showModalDialog
  • 스크립트를 계속 실행하도록 선택하더라도 "이 페이지의 스크립트가 사용 중일 수 있습니다 ..."대화 상자는 스크립트가 중간에있는 동안에도 크기 조정 및 흐림과 같은 이벤트가 실행되도록 허용합니다. Opera를 제외하고 바쁜 루프.
  • 얼마 전에는 Sun Java Plugin을 사용하는 IE에서 애플릿의 메서드를 호출하면 이벤트가 발생하고 스크립트가 다시 입력 될 수있었습니다. 이것은 항상 타이밍에 민감한 버그였으며 Sun이 그 이후로 수정했을 가능성이 있습니다.
  • 아마 더. 내가 이것을 테스트 한 지 오래되었고 그 이후로 브라우저가 복잡해졌습니다.

 

요약하면 JavaScript는 대부분의 사용자에게 엄격한 이벤트 기반 단일 실행 스레드를 갖는 것으로 보입니다. 실제로는 그런 것이 없습니다. 이것이 얼마나 단순한 버그인지, 그리고 얼마나 신중한 디자인인지는 분명하지 않지만 복잡한 응용 프로그램, 특히 크로스 윈도우 / 프레임 스크립팅 응용 프로그램을 작성하는 경우 사용자를 물릴 가능성이 있습니다. 간헐적으로 디버그하기 어려운 방법.

최악의 상황이 발생하면 모든 이벤트 응답을 간접적으로 처리하여 동시성 문제를 해결할 수 있습니다. 이벤트가 들어 오면 큐에 넣고 나중에 setInterval 함수에서 큐를 처리합니다. 복잡한 응용 프로그램에서 사용할 프레임 워크를 작성하는 경우이 작업을 수행하는 것이 좋습니다. postMessage 는 또한 향후 교차 문서 스크립팅의 고통을 덜어 줄 것입니다.

출처 : https://stackoverflow.com/questions/2734025/is-javascript-guaranteed-to-be-single-threaded
728x90
반응형