21.10.15 자바스크립트 동기 vs 비동기/ main thread /task queue/ /call stack/event loop/ AJAX

2021. 10. 15. 16:41작업/JavaScript

자바스크립트 동기 비동기란

웹의 발전 과정

서버에서 모든 데이터를 로드, 페이지 만듦(비동기X) -> AJAX(Asynchronous JavaScript And XML) 기술로 Client-Side로 서버 요청을 보내 데이터 처리 가능하게됨 -> XMLHttpRequest라는 객체로 서버로 요청

 

값으로서의 함수

1. 함수도 이다. function a(){} 와 같은 것은 var a=function(){} 로 가능하다는 뜻.

function a() {} // var a=function a(){} 함수라고 부른다.

//객체 안에 함수가 들어가있으면 메소드라고 부른다.
a={
	b:function(){
    }
};

2. 함수거 객체 내에 있다면 메소드 라고 부른다. 위 같은 상황에서 b는 key(속성, property)이고, function은 value(메소드)처럼 작용할 수 있다.

 

3. 또한 함수는 다른 함수의 인자로 전달될 수 있다. 예를 들어 cal(func,num) 이라는 함수와

increase(x) 라는 함수가 있다고 하면

alert(cal(sum,x)) 로 쓸 수도 있다는 뜻이다.

 

함수와 콜백

1. 반환값으로 함수를 사용하는 경우

//모드 전환에 따라 계산이 달라지는 함수를 정의
//이 함수 안에는 객체 1개가 정의되어 있고, return값으로 그 객체의 value를 내보낸다.
function cal(mode){
	var funcs={
    	'plus' : function(left,right){return left+right}
        'minus' : function(left,right){return left-right}
    }
    return funcs[mode];
}

alert(cal('plus')(2,1));
//답 3
alert(cal('minus')(2,1));
//답 1

현재 변수 funcs는 객체이고, plus와 minus는 key, 모드에 따라 실행되는 함수가 value값이다.
return으로 그 객체의 value를 내보내는데, 그 value는 함수이다.(메소드)

 

2. 배열 값으로 함수를 사용하는 경우

//function들을 배열의 원소로 사용했다.
var process={
  function(input){return input+10;},
  function(input){return input*input;},
  function(input){return input/2;}
};

var input=1;
for(var i=0;i<proceess.length;i++){
  input=process[i](input);
}
//이렇게 배열[i](인자) 로도 쓸 수 있다!

alert(input);

변수,매개변수,리턴값으로 쓰일 수 있는 애들을 first-class citizen(object)라고 한다.

 

 

콜백

다른 함수가 실행을 끝낸 뒤 실행되는 콜백 함수를 말한다. 자바스크립트에서 함수는 object,값으로 사용될 수 있기 때문에

다른 함수의 인자로 쓰일 수도, 어떤 함수에 의해 리턴될 수도 있다. 

이 때 인자로 넘겨지는 함수를 콜백함수라고 부른다.

변수 numbers에 배열 객체를 넣었다. .sort()는 메소드라고 한다.(자바스크립트가 기본으로 가진 내장메소드)
console log로 출력해보았는데 문자열로 정렬된 것 같다.. 

하지만 우리가 원하는 것은 숫자 크기로 나열. 따라서 .sort()에는 인자로 function을 넣을 수 있기 때문에 함수를 넣어줘본다.

더 간단하게 두 수의 차로 return하면 두 수중 누가 더 큰지 비교가 더 쉬움.

즉, 인자로 넣어준 sortfunc의 return값에 따라 numbers.sort() 메소드가 원하는 대로 출력이 됨을 알 수 있다.

여기서 sortfunc라는 함수를 콜백(Callback)함수라고 한다.콜백 함수는 '함수는 값으로 사용할 수 있다'라는 특성을 이용해, 함수(메소드)의 내부에서 또 함수를 호출하는 일인 것 같다.


동기 코드(Synchronous) vs 비동기 코드(Asynchronous)

자바스크립트는 한 번에 하나의 작업을 수행한다.

Memory Heap Call Stack 자바스크립트의 엔진의 주요 구성 요소이다.

Memory Heap이란?

변수와 객체의 메모리 할당을 담당하는 곳을 말한다.

Call Stack이란?

함수가 실행되는 동안 또다른 함수가 쌓이면 호출이 되면 쌓이는 곳이다. 

자바스크립트에서 함수를 호출하면 Call Stack이라는 곳에 호출 순서대로 차곡차곡 쌓인다.

그러고 나서, Stack은 맨 마지막에 호출된 함수가 맨 먼저 반환한다.

List in Frist Out, 먼저 들어온 것이 먼저 나간다라는 의미로, LIFO 구조라고 부른다.

 

동기(synchronous)란?

한 작업이 실행되는 동안 다른 작업은 멈춘 상태를 유지하고 자신의 차례를 기다리는 것을 말한다.

해당 코드 블록을 실행할 때 thread의 제어권을 넘기지 않고 순서대로 실행하는 것.

즉, 동기코드는 바로 Call Stack에 넣어진다.

동기 코드는 main thread에 의해 실행되므로, main thread를 블록할 수 있다.(만약 동기코드가 for i<10000000이라면 그 동안 main thread는 블록됨)

이러한 동작을 단일 스레드(싱글 스레드), 동기(Synchronous)라고 부른다.

 

동기(Synchronous) 동작 원리

  1. 코드가 실행되면 순서대로 Call Stack에 실행할 함수가 쌓인다.(push)
  2. 쌓인 반대 순서로 함수가 실행된다.(LIFO)
  3. 실행이 된 함수는 Call Stack에서 제거된다(pop)

비동기(asynchronous)란?

이전에 말했지만, 자바스크립트는 단일 스레드, 동기식으로 동작한다.

하지만 비동기는 어떠한 요청을 보내면 그 요청이 끝날 때까지 기다리는 것이 아니라, 응답에 관계없이 바로 다음 동작이 실행되는 방식을 말한다.

비동기 처리 코드를 감싼 블록은 task queue에 먼저 넣어지고, main thread가 동기 코드를 실행한 후에 제어권이 돌아왔을 때 event loop가 task queue에 넣어진 비동기 코드를 실행함. (event loop는 main thread로부터 제어권을 받아야 task queue를 체크할 수 있다.)

웹페이지를 리로드하지 않고 데이터를 불러오는 방식이며 Ajax를 통해서 서버에 요청을 한 후 멈추어 있는 것이 아니라 그 프로그램은 계속 돌아간다는 의미를 내포하고 있다.

 

 

비동기(asynchronous) 동작 원리

  1. Call Stack에서 비동기 함수가 호출되면 Call Stack에 먼저 쌓였다가 Web API(혹은 백그라운드라고도 한다)로 이동한 후 해당 함수가 등록되고 Call Stack에서 사라진다.
  2. Web API(백그라운드)에서 비동기 함수의 이벤트가 발생하면, 해당 콜백 함수는 Callback Queue에 push(이동) 된다.
  3. 이제 Call Stack이 비어있는지 이벤트 루프(Event Loop)가 확인을 하는데 만약 비어있으면, Call Stack에 Callback Queue에 있는 콜백 함수를 넘겨준다.(push)
  4. Call Stack에 들어온 함수는 실행이 되고 실행이 끝나면 Call Stack에서 사라진다. 

비동기 응답을 받으면, 응답을 처리하는 Callback 함수를 task queue에 넣는다. EventLoop는 Main Thread에 여유가 있을 때

task queue에서 함수를 꺼내서 실행한다.

 

브라우저의 main thread 는 자바스크립트 코드에서 동기적으로 처리되어야 할 코드실행 외에도, 웹페이지를 실시간으로 렌더링하고, 유저의 입력을 감지하고, 네트워크 통신을 처리하는 등 수많은 일을 처리한다.

비동기 작업을 할당하면, 비동기 처리가 끝나고 브라우저는 task queue에 실행 코드를 넣는다.

main thread는 event loop를 돌려 task queue에 작업이 있는지 체크한다. (event loop는 기존에 task queue에 존재했던 task들만을 처리하며, 새롭게 들어온 task들은 다음 iteration에 처리된다.)

작업이 있으면 task를 실행한다.

 

Q. 브라우저에서 Javascript가 어떻게 화면 전환하면서 HTTP 요청이나 여러 이벤트를 동시에 동작을 할 수 있는 것인가?

A. 하지만, 운 좋게도 브라우저에서의 자바스크립트 실행 환경(Runtime)에서는 자바스크립트 엔진 자체가 제공하지 않는 일부 기능인 DOM 조작이나 AJAX 같은 비동기 처리를 위한 web API를 제공한다.

또, 이를 제어하기 위해 이벤트 루프(Event Loop), 이벤트 큐(Callback Queue 혹은 task Queue)가 존재한다.

(출처: https://ljtaek2.tistory.com/142)

 

 

AJAX

  • Asynchronous Javascript And Xml(비동기식 자바스크립트와 xml)의 약자
  • 자바스크립트를 이용해 서버와 브라우저가 비동기 방식으로 데이터를 교환할 수 있는 통신 기능
  • 브라우저가 가지고있는 XMLHttpRequest 객체를 이용해서 전체 페이지를 새로 고치지 않고도 페이지의 일부만을 위한 데이터를 로드하는 기법
  • AJAX는 HTML 페이지 전체가 아닌 일부분만 갱신할 수 있도록 XMLHttpRequest객체를 통해 서버에 request한다. 이 경우, JSON이나 XML형태로 필요한 데이터만 받아 갱신하기 때문에 그만큼의 자원과 시간을 아낄 수 있다.

즉, 쉽게 말하자면 자바스크립트를 통해서 서버에 데이터를 비동기 방식으로 요청하는 것이다.

(출처: https://velog.io/@surim014/AJAX%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80)