-
비동기 작업의 이해web 2023. 3. 26. 17:10
리액트를 공부하다보면 동기, 비동기에 대한 이야기를 정말 많이 접할 수 있지요, 특히 데이터 패칭을 시작하면 자바스크립트 비동기 작업에 대해 반드시 짚고 넘어가야하더라고요 그래서 오늘은 비동기 작업에 대한 이야기를 해보려고 합니다. 사실 비동기는 그렇게 어려운 내용이 아닙니다.
비동기란?
예를 들어, 과제가 1부터 10까지 있는데, 과제 1을 하는데에는 막 3시간이 걸리고, 과제10을 하는데에는 10분이 걸린다고 칩시다. 그럼 우리 생각에는 과제 10을 먼저 할 수도 있는 거잖아요, 그런데 동기는 그런 거 없이 정직하게 하는 거에요. 과제1시작해요, 끝나면 과제2시작하고요 끝나면 과제3하고 이런식입니다. 그런데 비동기는 이렇게 순서대로 하지 않아요. 앞에 작업이 끝났든 안 끝났든 다음 테스크를 할 수 있어요. 과제 1하다가 그냥 과제10먼저 하고 이렇게 할 수도 있고, 과제 1이랑 과제10이랑 동시에 할 수도 있어요.
이 이야기를 왜 하냐면요, 우리가 서버의 API를 호출할 때, '닉네임 API야 멤버들의 닉네임 데이터가 필요해 요청할게~'하고 응답을 받는 과정! 이 때 이 과정이 비동기적으로 이루어집니다. 그러니까 내가 데이터를 요청하면 응답이 올 때까지 기다려야해요. 내가 요청한 순서대로 데이터가 오지 않을 수도 있고요, 여러가지 요청했을 때 동시에 데이터가 올 수도 있는거죠. 만약에 이 작업이 동기적으로 이루어진다면, 요청이 끝날 때까지 다음 작업을 할 수 없어요. 요청이 끝날 때까지 기다려야하는데, 비동기적으로 하니까 그렇게 기다릴 필요 없이 웹이 멈추지않고 돌아갈수가 있습니다.
콜백 함수
그리고 이렇게 비동기 작업을 자바스크립트에서 수행하게될 때 사용하는 방법이 바로 콜백 함수입니다. 그러니까 요청을 보냈을 때 세월아네월아 응답이 오길 기다리는 게 아니라, 특정이벤트가 발생했으르 때 호출을 원하는 내용을 콜백 함수에 전달하는 겁니다.
이렇게 자바스크립트에서 비동기프로그래밍을 하기 위해서 콜백함수를 쓰는데, 이 때에는 (1) 비동기적으로 콜백함수를 호출하는 함수와 (2) 비동기적으로 호출되기를 원하는 콜백함수가 필요해요. 어떻게 보면 콜백함수는 함수 안에서 또 다른 함수를 실행하는 함수다라고 말할 수도 있어요. 즉, 함수를 만들 때 인풋값을 함수 자체로 넘겨주고, 때가 되면 나중에 호출, 나중에 콜백한다는 겁니다.
왼쪽을 먼저 보면, 제가 콜백이라는 이름의 함수를 썼죠. 그리고 이 콜백이라는 함수는 프린트라는 함수를 받아와서 프린트라는 함수를 보여줘라라는 뜻이에요. 이게 비동기적으로 호출되기를 원하는 콜백함수고요, 이 아래 콜백함수를 호출하죠. 그리고 콘솔에 하이라고 뜨게 하는 함수를 넣어줘라는 의미죠. 그러니까 여기 콘솔에 하이라고 뜨게 해줘함수가 프린트 함수 부분으로 들어가서 뜨는 겁니다. 즉, 여기서는 비동기적으로 콜백함수를 호출했어요. 오른쪽도 마찬가지인데요, 여기서 setTimeout은 콜백함수의 실행을 지정된 밀리초만큼 지연하는 자바스크립트 내장함수입니다. 여기서는 프린트 함수를 3초 뒤에 호출해줘!라는 의미겠죠.
예를 들어서, 우리가 콘솔에 위와 같이 입력한다면 순서대로 1 2 3 이 뜨지요.
그런데 이렇게 setTimeout을 쓰게 되면 순서가 1 3 2 로 뜨게 됩니다.
Promise
그런데 이렇게 콜백함수 안에 또 콜백 함수를 넣고 콜백 함수를 넣고 중첩되게 구현을 할 수가 있어요, 콘솔에 입력하면은 그냥 Hi~가 세번 뜨긴 하는데요, 이게 가독성이 그리 좋지가 않죠. 이런식으로 중첩되게 들어가서 가독성이 떨어지는 요런 형식의 코드를 콜백 지옥이라고 합니다. 이러한 형태의 코드는 우리가 지양해야할 코드에요. 그런데 그렇다면 콜백 지옥을 만들지 않게 할 수 없을까요? 가능합니다! promise를 이용한다면요.
자 promise는 언젠가는 너에게 도착할게!라고 약속하는 아이라고 생각하시면 되어요. promise를 이용하면 위에서 처럼 계속 중첩되는것을막을수있기 때문에 콜백 지옥을 해결할 수 있고요, 여기서 코드를 잠시 살펴보면, .then을 쓰고 나면 이게 Promise에서의 값을 받아오게 됩니다.
그리고 .catch는 에러가 나면 이걸 통해서 알 수가 있어요. 즉, promise는 여러 작업을 연달아 처리한다고 해서 함수를 여러번 감싸는 게 아니라, .then을 이용해서 그다음 작업을 설정하는 겁니다. 그래서 콜백 지옥이 형성되지 않습니다.
async / await
그리고 이 Promise를 좀 더 쉽게 이용할 수 있도록 돕는 아이들이 있어요, 바로 async(에이싱크)/await 기능입니다. 이 친구들은 비동기의 핵심이라고 할 수 있어요.
자 결국 Promise를 이용해도, promise then promise then promise then이게 반복이 되죠. 그래서 이걸 좀 더 쉽게 할 수 있도록 async와 await이 나왔습니다. 새로운 게 추가된 게 아니고 기존의 Promise에 좀 더 얹어주는 느낌이에요. 여기 이렇게 함수 앞에 async라는 키워드를 붙여주면 자동적으로 함수가 Promise로 변환이 됩니다. await은 async가 붙은 함수 안에서만 사용할 수가 있고, 말 그대로 좀 기다리는 거에요. promise가 처리될 때까지 함수 실행을 기다리는 거죠. promise가 처리되면 다시 실행이 재개가 됩니다. 이게 앞에서 promise.then의 역할을 대신해주는 게 await이라고 생각하시면 됩니다.
사실 비동기 작업은 공부를 해도해도 끝없이 까먹게 되더라고요, 오늘 글을 통해서 비동기 작업에 대해 잘 이해하셨기를 바랍니다!
'web' 카테고리의 다른 글
리액트 반응형 완벽 구현하기 (1) 2023.04.23 프리티어 오류 해결하기 (1) 2023.04.16 [리액트/자바스크립트] S3파일 다운로드 (3) 2023.04.02 API 통신 한 방에 이해하기! (1) 2023.03.19 자바스크립트에서 객체지향 프로그래밍을 해야할까? (4) 2023.03.08