▶️ 브라우저의 자바스크립트 동작방식

  print(1+1) // 1 출력 
  time.sleep(1) // 1초 쉬고  
  print(2+2) // 4 출력
  • 파이썬은 내부에서 코드를 읽을 때 위부터 차례대로 읽기 시작한다. 이 코드에 경우 1이 출력되고, 1초 쉬고 4가 출력된다.
  • 이처럼 위부터 아래로 한번에 코드를 한줄씩 처리하는 것을 동기식 처리(synchronous) 라고 한다. 거의 모든 프로그래밍 언어가 이 방식을 차용하고 있다.
  • 파이썬처럼 자바스크립트를 실행하는 웹브라우저 또한 Stack이라는 연산 공간에서 한번에 한 줄씩 코드를 실행한다.
//브라우저 콘솔 
  console.log(1+1); 
  console.log(2+2);
  setTimeout(function(){}, 1000)
  console.log(3+3);

  /*출력결과 
  2
  4
  6(1초 쉬지않고 바로 출력) 
  */
  • 그런데 브라우저 콘솔에서 해당 코드를 실행할 경우 순차적으로 코드를 실행함에도 불구하고, 3번째 코드가 실행되지 않아 6이 1초 뒤에 출력되야함에도 바로 출력된다.
  • 이는 JS 만이 갖는 타언어와의 다른점으로, 이렇게 오래걸리는 작업을 실행시 해당 작업을 후순위로 밀어 다른 작업부터 처리하게 하는 방식이다.
  • 이러한 처리방식을 전문용어로 비동기식 처리(asynchronous)라고 한다.

▶️ 웹브라우저와 stack 의 원리


  • 우리가 사용하는 웹브라우저는 C++로 만들어졌는데, 브라우저는 실행해야할 자바스크립트 코드를 발견하면 stack에 넣어 돌린다.
  • stack은 코드를 해석해서 맨 윗줄부터 하나하나 실행시키는 공간이다. 브라우저 내부에 한개만 존재하고, heap 이라는 공간에 저장된 변수들을 가져다 사용한다.
  • stack은 한번에 한 코드만 실행할 수 있어 single thread language 라고 불린다.
  • 즉 이러한 웹브라우저의 비동기적 처리는 JS가 아닌 웹 브라우저의 특성에 기반한 것이다.

▶️ stack의 동작 방식

  • 셋타임아웃, Ajax 요청 코드 등 처리시간이 오래걸리는 코드들은 Stack에 쌓아놓지 않고, 대기실같은 공간(Web api)에 잠깐 보류해놨다가 완료되는 시점에 Stack으로 보낸다.
  • Stack은 항상 바쁘기때문에, Stack이 텅 빈 시점에만 보류된 코드를 불러온다.
  • 실행준비가 되면 이런 코드들을 Queue라는 대기장소에 집어넣고, 들어온 순서대로 처리한다. (권총에 탄창을 넣고- 공이를 당기고- 방아쇠를 당겨 발사하는 과정을 떠올려보자.)
  console.log(1+1); //1번
  setTimeout(function(){console.log(2+2)}, 1000)//2번
  console.log(2+2);//3번
  console.log(3+3);//3번


  /*출력결과 
  2
  4
  6
  */
  • 이에 따라 위의 코드를 해석하면,
  1. 일단 세 코드를 모두 queue에 불러서 대기열을 만든다.
  2. 1번 코드를 Stack으로 보내 바로 실행시키고, 2번 코드는 처리시간이 오래 걸리므로 처리를 보류하고, queue의 4번 코드의 후순위로 대기한다.
  3. 3,4번 코드를 처리한 후, 후순위에 있는 2번 코드가 실행된다.
    라는 뜻이다.

▶️ stack의 동작 방식에 따른 문제점과 솔루션

	for (let i = 0; i < 1e10; i++) {
    	i++;
    }
  • Stack과 queue의 이런 특성때문에, 이렇게 100억번 돌리는 단일 반복문을 돌리면 시간이 오래걸릴 수 밖에 없다. 10초 동안 연산을 한다고 하면 10초 동안 사용자는 아무것도 할 수가 없는 것이다.

▶️ 문제 해결법 1. setTimeout 사용

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

▶️ 문제 해결법 2. web worker 사용

//main.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라는 특별한 함수가 있다. 
  • Web worker는 스크립트가 웹페이지 이용해 지장을 주지 않도록 별도의 작업쓰레드를 만들어 병렬처리하도록 돕는다.
  • 사용자의 이용환경을 개선하기 위해 멀티쓰레드 작업이 필요할 경우 사용하면 된다. 더 자세한 이용환경은 https://developer.mozilla.org/ko/docs/Web/API/Web_Workers_API/Using_web_workers
    에서 확인해보도록 하자.

profile
관조, 사유, 끈기

0개의 댓글

관련 채용 정보

Powered by GraphCDN, the GraphQL CDN