JavaScript(웹브라우저작동원리/JS동작원리)

4290 단어 JavaScriptJavaScript

자바스크립트는 항상 동기식 처리 (synchronous)

<script>
  console.log(1); 
  console.log(2); 
  console.log(3);
</script> // 1,2,3 차례대로 출력

자바스크립트는 비동기처리 (asynchronous)도 가능

  • 특수한 코드들을 발견하면 약간 제쳐두고 다른 코드부터 실행
console.log(1);
setTimeout(function(){console.log(2);}, 1000);
console.log(3); // 1,3 출력 (1초후) 2 출력

만약 처리가 오래걸리는 코드(ex. ajax 요청, 이벤트리스너, setTimeout)를 실행하게 되면 stack에 쌓여서 실행하지 않고 잠깐 보류된다.(브라우저는 C++언어로 구성되어 있다. 브라우저는 실행해야할 자바스크립트 코드를 발견하면 C++언어로 만들어둔 stack에 넣어 작동한다. )

실행이 준비되면 Queue에 집어넣어지고 Queue에 있던 코드는 stack으로 옮겨서 실행하게 된다. 단, stack이 비어있는 상태에 집어넣어서 실행이 가능하다.

만약 반복문을 100억번 돌리는 코드를 실행해야한다면?

for (let i = 0; i < 1e10; i++) {
  i++;
}

1. setTimeout을 이용.

setTimeout()을 이용해서 0초마다 0~1억 반복, 1억~2억 반복, 2억~3억 반복...
이렇게 코드를 실행하면 보다 쾌적하게 작업을 실행 가능하다.
0초마다 Queue로 보내기 때문에 그 사이사이에 사용자의 이벤트리스너 같은 코드가 실행가능.
(setTimeout 타이머를 0초로 설정해도 실은 4ms로 동작, 설정가능한 최소시간이 4ms)

2. Web worker를 이용.
다른 자바스크립트 파일을 이용해서
그 파일에서 힘든 연산을 시키고 그게 완료가 되면 값을 가져오라고 명령이 가능하다.
이미 만들어진 Worker라는 클래스를 사용하면 된다.
worker.js에서 작업이 완료될 시 postMessage() 이렇게 실행하면 다른 파일로 완료된 결과값을 전달 가능.
참고: mdn web docs , web worker 간단 정리하기

(메인 js 파일)
var myWorker = new Worker('worker.js'); 
w.onmessage = function(e){
  console.log(e.data) //이러면 1 나올듯
};
----------------------------------------
(worker.js 파일)
var i = 0;
postMessage(i + 1); //postMessage라는 특별한 함수가 있음

만약 두개의 함수를 차례로 출력하고 싶다면?

만약 첫째함수의 1을 출력하고, 둘째함수의 2를 차례로 출력하고 싶다면, 파이썬과 같은 언어로는 다음과 같은 코드가 정상적으로 작동한다.

function 첫째함수(){
  console.log(1)
}
function 둘째함수(){
  console.log(2)
}
첫째함수(); //1 출력
둘째함수(); //2 출력

자바스크립트는 비동기라는 특수성으로 인해 위와 같이 작성한다고 순차적으로 실행하는걸 보장하지 않는다. 만약 첫째함수가 setTimeout 또는 Web API 대기실로 보내지는 코드를 가지고 있다면 나중에 실행되기 때문이다.)

따라서, 첫째함수안에 인자값으로 둘째함수를 주고, 파라미터값에 함수자체를 주어서 함수내에서 함수를 실행하게 하는 방법이다. 그렇다면 무조건 첫째함수가 먼저 실행되고, 둘째함수가 실행될 것이다.

function 첫째함수(콜백){
  console.log(1);
  콜백();
}
function 둘째함수(){
  console.log(2)
}
첫째함수(둘째함수);

콜백함수 지옥의 단점

순차적으로 실행하려고 콜백함수를 여러개 사용하다 보면 코드가 옆으로 길어지고, 콜백 함수를 익명 함수로 전달하는 과정이 반복되어 코드의 들여쓰기 수준이 감당하기 힘들정도로 깊어지는 현상이 생긴다. 주로 이벤트 처리나 서버 통신과 같은 비동기적인 작업을 수행하기 위해 이런 형태가 자주 등장하는데, 가독성이 떨어지면서 코드를 수정하기 어렵다.

따라서, 콜백함수 대신 사용할 수 있는 promise 디자인 패턴이 존재 - https://velog.io/@pjh1011409/JavaScriptPromiseasyncawait

좋은 웹페이지 즐겨찾기