비동기적으로 실행된다는 것은 하나의 동작이 완료되지 않아도 다음 코드가 실행되는 것을 의미한다. 자바스크립트가 싱글 스레드를 가지면서도 비동기로 동작할 수 있는 원리는 바로 브라우저에 있다. 브라우저에 있는 Web API가 멀티스레드로 동작하기 때문이다.
<aside> 💡 Thread 는 기본적으로 프로그램이 작업을 완료하는데 사용할 수 있는 단일 프로세스로, 각 스레드는 한 번에 하나의 작업만 수행할 수 있다.
</aside>
알잘딱깔센 JavaScript
자바스크립트 실행 환경을 살펴보면 자바스크립트 엔진의 콜 스택에 실행될 함수가 쌓이게 되는데, 비동기로 실행될 때는 Web API를 호출하게 된다. Web API에서는 콜백 함수를 콜백 큐(테스크 큐)에 추가하게 되고 이벤트 루프는 콜백 큐와 콜 스택을 보면서 콜 스택이 비면 콜백 큐의 함수를 꺼내 콜 스택에 넣는다. 이벤트 루프와 콜백 큐가 있기 때문에 콜 스택이 하나여도 비동기 동작이 가능하다.
비동기 특성은 서버에 요청을 보내고 결과가 돌아오지 않아도 다음 코드를 실행한다. 비동기 방식이 필요한 이유는 웹에서 서버에 데이터를 요청했을 때 요청이 완료되기 전까지 아무것도 실행되지 않는다면 화면이 멈춘 것처럼 보일 뿐 아니라 하나의 프로그램을 실행하는 데 많은 시간이 소요되기 때문이다.
하지만 실행 순서가 중요할 때도 있다. 예를 들면 다른 코드가 서버에 요청한 데이터 값을 이용해야 할 때는 데이터를 받아 온 후에 코드가 실행되는게 필요하다. 이럴때 사용하는 것이 비동기 처리이다.
let response = fetch('mySnack.jpg');
let snackImg = response.snackImg(); //서버에서 이미지를 가져오면 이미지 크기, 네트워크 환경에 따라 실행 불가한 경우 발생, 비동기 처리 필요
비동기 처리의 종류에는 Promise
, await/async
, fetch
등이 있다.
Promise
는 ES6에 도입되었으며, 응답에 관한 정보를 갖고 있는 객체로 then, catch를 통해 결과 값을 처리한다. await/async
는 ES2017에서 도입되었고 Promise를 기반으로 하지만 then, catch를 사용하지 않고 try-catch를 사용한다. 마지막으로 fetch
는 접근하고자 하는 url과 매개변수로 네트워크 요청을 보낼 수 있다. 지금부터 비동기 처리의 종류에 대해서 더 자세히 알아보자.
자바스크립트는 함수의 매개변수로 어떤 자료형이 들어올지 걸러주는 문법이 없다. 따라서 null과 undefined를 제외한 모든 자료형을 전달할 수 있다.
함수도 하나의 object
이므로 매개변수로 전달될 수도 어떤 함수에 의해 return 될 수도 있다. 이렇게 다른 함수에 인자로 전달되는 함수, 그 함수 자체를 콜백함수(callback function) 라고 한다. 매개변수로 넘겨진 함수는 넘겨 받고 이를 실행할 수 있도록 나중에 다시 불러야 하는데, 이 불러달라는 것에 착안하여 Call Back이라는 이름이 붙었다.
즉 함수 A의 호출에서 매개변수로 함수 B가 전달되어, 특정 이벤트가 발생했거나 특정 시점이 되면 다시 호출되는 함수 B를 콜백 함수라고 말한다.