FRONTEND/JavaScript

asynchronous function

MarkLEE 2021. 5. 20. 16:56

오늘은 학습에 어려움을 많이 겪었던 비동기적 함수에 대해 정리를 해보려고 한다. 

우선, asynchronous라는 것은, "비동기적"이라는 뜻이다. 

 

비동기적이라는 것은 무엇일까?

 -> 비동기적이라는 것은 '동기적이지 않다.' 라는 뜻이다. 

 -> 그렇다면, 동기적이라는 것은 무엇인가? 우리가 쉽게 생각할 수있는 callstack을 생각하면 된다. 순서를 기억하고, 그 순서에 따라 실행하는 것을 의미한다. 

 -> 그렇게 생각해본다면, 비동기적이라는 것은 호출된 순서에 상관없이, 여러 녀석들의 작업을 진행하고, 빨리 종료된 녀석들 부터, 출력되는 것을 의미한다는 것을 알 수있다. 

 

이는 eventloop라는 개념을 통해 접근 하면 보다 이해하기 쉽다. 

그러므로 여기서 잠시 eventloop라는 개념을 짚고 넘어가자. 

 

우리가 자주 이용하고 있는 chrom 의 경우, single-threaded browser이다. 즉, 한번에 한가지의 일밖에 처리를 하지 못한다는 것이다. 

여기서 간단한, 예를 들어 이를 이해해보자.

 

function zoo(){

console.log("Hi!")

}

function bar(){

zoo()

}

function foo () {

bar();

}

 

foo();

위와 같은 코드가 있다고 가정하자. 그렇다면, browser는 function, zoo, bar, foo를 순서대로 등록을 하고

가장 밑에 있는 foo()를 만나 등록되어 있던 foo를 실행하게 된다.

 

그런데 foo를 실행하고 보니, bar를 실행하라고 하기에, 다시 위에 있는 bar를 찾아가고, 같은과정을 반복하여 가장 위에 있는 zoo까지 가서, "Hi"가 실행되게 된다. 직관적으로 어렵지 않다. 

하지만 이게 어떻게 실제적으로 stack에 쌓이는 것일까? 

 

console.log("hi")
zoo()
bar()
Foo()

위와 같이 실행 순서대로 밑에서부터 위로 쌓이게 되고, 위에 있는 것들이 하나하나 지워지면서, 마지막에 쌓여 있던 foo()가 사라지게 된다. 

 

그리고 이렇게 call-stack에 쌓여 있는 일들은 하나씩 하나씩 처리가 되게 되고, 해당 일을 하는 동안은 다른일을 하지 못한다. 

이러한 문제점을 해결하기 위해서, 나온것이 "비동기적"이라는 개념이다. 

 

만약 우리가 비동기적인 무언가를 실행하게 되면, 예를들어 비동기적함수 setTime(callbackfunc, 1000)이라고 하자. 

callstack에 쌓이고, 1초가 지나고 실행이 된후, 다음것이 등록&실행되는 것이 아니라, 바로 webAPI로 넘기게 된다. 

그럼 webAPI에서, 해당 1초가 지난후, setTime의 callbackfunc을 taskque로 넘기고, 쌓여 있게 된다. 

 

그리고 드디어 여기에서 eventloop가 등장한다. 

 

eventloop는 이렇게 taskque에 쌓여 있는 녀석들을 call-stack으로 보내 js가 처리하게 하는데, 

아무때나 바로바로 callstack으로 보내는 것이 아니라, 나름의 기준이 있다. 

 

그 기준은 바로 call-stack이 완전히 비어있을 때이다. 

 

그러므로, 만약에 1초가 지나고, callbackfunc가 taskque에 쌓여 있다고 하더라도, 현재 call-stack에 무언가가 쌓여 있다면, 

eventloop는 기다렸다가, 모든 것들이 call-stack에서 사라진뒤에서야 callbackfunc을 call-stack에 쌓는 것이다.

 

해당내용의 출처를 아래에 남긴다.

https://www.youtube.com/watch?v=8aGhZQkoFbQ&t=526s

 

 

비동기적이라는 것은 여러 task를 동시에 진행할 수 있기때문에, 꽤나 많은 장점을 지닌것으로 보인다. 

다음 게시물에서는 이런 비동기적인 것들을 제어하는 방법인 (promise, callback, async&await)에 대해 알아보려고 한다.