[CS] 동기/비동기에 대해서 알아보자(sync/async)

놀고있는 자원을 효율적으로 사용하는 비동기에 대해서 알아보자

오늘은 동기와 비동기에 대해서 설명하고자 한다.

해당 개념은 설명만 들으면 쉽게 이해가 될 수도 있지만, 헷갈릴 여지도 많은 개념이라고 생각한다.

특히 스레드 개념과 엮이기 시작하면 많이 헷갈리기 시작하는 개념이다.

동기(Sync)

동기가 제일 간단하다. 흔히 우리가 쓰는 코드를 상상하면 된다.

아래 JS 예제가 있다.

console.log(1)
console.log(2)
console.log(3)

 결과는 위에서부터 순차적으로 실행되어 아래와 같은 결과를 보일 것이다.

코드 결과

비동기(Async)

자 이제 비동기에 대해 이해해 보자. 단순하게 비동기는 동기의 반대말이다. 동기가 순차적으로 실행되는 것을 의미하니까 비동기는 순차적으로 실행되지 않는다고 생각하면 된다. 순차적으로 실행되지 않는다면, 코드의 실행순서를 파악하기 힘들 것이다. 이렇게 생각했을 때 비동기가 정말 필요한지에 대해 의문점이 생긴다.

비동기의 필요성

비동기가 등장한 이유는 낭비되는 시간이 아까워서이다. 아래와 같은 코드를 보자

// 해당 코드는 psuedo 코드이다.

//1
const reqBody = {
	"choding": "is good"
}

//2. 해당 http 요청이 100초가 오래걸린다는 것을 가정하자
const response = requests.post("http://localhost:3000", reqBody)

//3
console.log(response.body)

// 이후 필요한 로직 실행!

단순하게 http 요청을 보내는 코드이다. 이 코드가 동기적으로 작동한다면 대락 100초 이후에 console.log(response.body)가 실행되고 이후 로직이 작동할 것이다. 근데 http 요청을 보내고, 받는 100초 동안 프로세스는 무엇을 하고 있을까?

정답은 “아무것도 안하고 있다.” 이다. 정말 아무것도 안 하고 http 응답을 받는 순간까지 기다리는 것만 진행할 것이다. 만약 이 100초라는 시간에 다른 작업을 하면 어떨까? 웬만하면 많은 작업들을 처리할 수 있을 것이다.

이 남는 시간을 활용하기 위해 비동기라는 개념이 등장했다.

비동기 작동 과정

위 그림처럼, 2번이 완료되지 않았음에도, 2번의 응답이 오기까지의 시간동안 다른 작업을 하는 것이 바로 비동기라고 할 수 있다.

콜백

앞서 비동기의 필요성을 말했다. 그렇다면 100초 동안 비는 시간에 다른 작업을 하고 나서, 응답을 받는 순간에는 어떻게 될까? 해당 값으로 처리하는 로직이 필요할 것이다. 그것이 바로 콜백(callback)이다.

콜백의 주요 논지는 “해야할 일을 뒤로 미루는 것” 이다.

사실, 이름만 봐도 알 수 있다. callback은 회신하다/답신하다는 뜻이다.

그러니까 “할일 다 하고(=해야 할 일 미루고), 네가 요청한 일 처리할 수 있을 때 처리하겠다"라는 것이다.

아래 코드를 다시 보자.

2번 과정이 100초가 걸리니까, 2번의 응답이 오는 100초 동안 다른 일을 JS가 한다고 하자. 이후 100초가 지난 후, 2번의 응답을 가지고 무언가 작업을 해야 할 것이다. 그런데, 어떻게 실행할 것인가? 

// 해당 코드는 psuedo 코드이다.

//1
const reqBody = {
	"choding": "is good"
}

//2. 해당 http 요청이 100초가 오래걸린다는 것을 가정하자
requests.post("http://localhost:3000", reqBody)

//3
console.log(response.body)

// 이후 필요한 로직 실행!

//100초 후...

//어라, 어떻게 응답을 처리하지?
//응답은 왔는데.... 처리할 코드를 어떻게 작성하지...?

이때 콜백을 작성하면 응답을 처리할 수 있는 코드를 작성할 수 있다.

// 해당 코드는 psuedo 코드이다.

//1
const reqBody = {
	"choding": "is good"
}

//2. 해당 http 요청이 100초가 오래걸린다는 것을 가정하자
requests.post("http://localhost:3000", reqBody, function(response){
	// 4. 100초 후 이 함수 실행
	console.log(response.data)
})

//3
console.log(response.body)

위 처럼 콜백 함수를 작성할 수 있을 것이다. 저 4번 콜백 함수는 http 응답이 오면 실행된다.

4번의 콜백 함수는 앞서 말한 “해야 할 일을 뒤로 미루는 것"과 같다.

마무리

간단하게 비동기와 콜백에 대해 알아보았다.

이렇게 보면 비동기 자체는 크게 어렵지 않은 것 같다. 하지만 필자도 이 개념을 오해 없이 이해하기에 많은 시간이 들었다.

여러분들도 오해없이 비동기를 이해할 수 있게 되었으면 좋겠다.