JavaScript/ES6

[ES6]동기/비동기처리와 콜백함수란?

MoZZANG 2022. 8. 30. 14:35
 자바스크립트는 항상 동기식 처리 (synchronous)

 

동기식 처리가 뭐냐면 한번에 코드 한줄씩 차례차례 실행된다는 소리입니다.

자바스크립트를 실행하는 웹브라우저는 stack이라는 코드 실행 공간이 있는데

거기서 코드를 한줄한줄 차례로 실행합니다. 

그럼 하단 코드는 어떤 순서대로 출력될까요? 

 

예상하신 대로 1,2,3이 차례로 출력됩니다.

왜냐면 자바스크립트는 한번에 코드 한줄씩 차례차례 실행하니까요.

이걸 전문용어로 동기적이다~ (synchronous) 라고 합니다. 

그냥 거의 대부분의 프로그래밍 언어들은 이런 특징을 가지고 있습니다. 

 

 

 

 

 

비동기처리 (asynchronous)라는 것도 가능합니다

 

특정 코드를 1초 후에 실행하고 싶으면 어떻게하죠?

일반적인 프로그래밍 언어에서 이런 코드를 작성하려면......

 

▲ 파이썬으로 해보았습니다. 이렇게 작성합니다.

time.sleep(1)이라는건 1초 쉬어주세요 라는 뜻입니다.

그럼 1이라는게 출력되고 / 1초 쉬고 / 2라는게 출력됩니다. 

 

 

 

자바스크립트에서 1초 쉬고 뭔가 출력하는 코드를 작성하려면

왜그러냐면 setTimeout() 이라는 함수를 잘 보시면 이건 실행까지 시간이 조금 걸리는 함수죠?

1초나 걸립니다. 

자바스크립트 실행머신인 웹브라우저는

이런 특수한 코드들을 발견하면 약간 제쳐두고 다른 코드부터 실행하려고 합니다. 

그래서 setTimeout() 을 제껴두고 그 밑에 있는 console.log(2)라는 코드 부터 실행하는 것입니다. 

 

 

이런 처리방식을 바로 비동기(asynchronous)라고 합니다.

실행이 오래걸리는 그런 코드들은 잠깐 대기실에 제쳐두고,

실행이 바로바로 가능한 코드들부터 처리하는 방식을 뜻합니다. 

이건 자바스크립트 언어 자체의 기능이 아니라

자바스크립트 실행을 도와주는 웹브라우저 덕분에 해낼 수 있는 것입니다. 

 

 

 

 

 

잠깐 코드를 제쳐두는 대기실

 

실행을 미루고 옆으로 잠깐 제껴둘 수 있는 코드들은 미리 정해져있습니다.

위에서 말했던 setTimeout, addEventListener, ajax 관련 함수들이 바로 그것입니다. 

setTimeout, addEventListener, ajax관련 함수들은 1초대기, 클릭대기 이런걸 하는 코드들인데

이런 코드들의 특징은.. 읽는 시점과 동작 시점이 차이가 있습니다. (쉽게 말하면 동작까지 오래걸립니다.)

 

 

자바스크립트를 실행하고 해석하는 크롬쨩은 이런 특별한 코드들을 만나면

1. 잠깐 대기실에 제껴두고 2. 준비가 완료되면 다시 실행시킵니다. 

 

 

▲ 크롬쨩은 위의 코드를 읽다가 setTimeout~ 이런 코드를 만나면 잠시 Web API 대기실로 옮겨서 대기시킵니다.

그리고 1초의 대기시간이 지나고 setTimeout이 완료가 되면 대기실에서 코드를 꺼내서 코드가 실행되게 만들어줍니다. 

 

이것 덕분에 setTimeout같이 시간이 오래걸리는 코드들을 비동기식으로 처리할 수 있는 것입니다.  

그래서 자바스크립트는 평소에 별일 없으면 동기식으로 처리하는데

비동기를 지원하는 setTimeout 같은 함수를 이용하면 비동기식으로 동작하게 만들 수 있는 언어입니다. 

 

 

 

 

 

콜백함수를 이용한 순차적 실행

자바스크립트는 비동기상황 등에서 코드를 순차적으로 실행하고 싶을 때 콜백함수를 적극 활용합니다. 

콜백함수라는 건 별거없고 그냥 함수안에 들어가는 함수를 전부 콜백함수라고 부릅니다. 

 

어떻게 했길래 콜백함수를 쓰면 순차적으로 실행되는건지 혹시 궁금하지 않으십니까.

 

 

 

 

 

콜백함수 디자인하는 법

 

예를 들면 순차적으로 실행하고 싶은 함수가 두개 있다고 칩시다.

그럼 이렇게 코드짜면 될까요?

 

여러분이 파이썬으로 코드짜신다면 이게 맞습니다.

하지만 자바스크립트는 비동기라는 특수성으로 인해 이렇게 쓴다고 순차적으로 실행하는걸 보장하진 않습니다. 

(첫째함수가 뭐 setTimeout이라든지 Web API 대기실로 보내는 코드라면 나중에 실행될 수 있으니까요)

 

 

그럼 우리도 이거랑 똑같이 개발하면 될 것 같습니다.

콜백함수를 만들어서 첫째함수(둘째함수);

이런 식으로 실행시킬 수 있게 만들어놓으면 순차적으로 실행할 수 있겠죠? 

그럼 어떻게 코드를 짜놔야 함수를 함수안에 집어넣을 수 있을까요?

 

 

함수에 파라미터를 하나 뚫어주시면 됩니다.

그리고 그 파라미터에 소괄호를 붙여서 실행해주세요~ 라고 하면 함수안에 함수를 집어넣어서 실행이 가능합니다. 

이게 콜백함수 디자인하는 법입니다. 

 

 

위처럼 미리 만들어놓은 함수를 집어넣을 수도 있고

 

 

이렇게 직접 함수선언문을 집어넣을 수도 있습니다. 

 

 

 

 

순차적으로 실행하려고 콜백함수를 여러개 사용하면 단점이 조금 있습니다.

코드가 옆으로 길어집니다. 

 

첫째함수 둘째함수 셋째함수 이렇게 차례로 실행해주는 코드입니다.

특히 자바스크립트로 서버개발시 이런 패턴 흔합니다. 

이런거 보기싫으시면 ES6 신문법인 Promise라는 기계를 만들어 사용하시면 됩니다. 

 

 

콜백대신 쓸 수 있는 Promise 디자인 패턴을 적용하면 어떻게 되냐면

옆으로 길어지지 않고 then이라는 키워드 덕분에 그나마 뭘 하는지도 파악이 쉬워집니다.

어떻게 하는지는 promise 포스팅에서 알아봅시다. 

 

 

 

 

 

출처 : 코딩애플의 매우쉽게 이해하는 JavaScript 객체지향 & ES6 신문법

'JavaScript > ES6' 카테고리의 다른 글

[ES6]Promise 예제  (0) 2022.08.30
[ES6]인간의 언어로 설명하는 Promise  (0) 2022.08.30
[ES6]import / export  (0) 2022.08.30
[ES6]Destructuring(구조분해)  (0) 2022.08.30
[ES6] class,extends,getter,setter 연습문제  (0) 2022.08.25