자바스크립트는 싱글 스레드 언어이기 때문에 한 번에 하나의 작업만 수행할 수 있다.

이전 작업이 완료되어야 다음 작업을 수행할 수 있다. 이러한 코드 순차 실행을 동기(Synchronous)라고 한다.

그러나 작업이 오래 걸리거나 응답이 늦어지는 경우에 전체적인 성능에 영향을 줄 수 있다. 예를 들어 서버에 데이터를 요청하고 응답을 받아야 하는 작업이 있다면, 응답이 올 때까지 대기해야 한다.

이러한 문제를 해결하기 위해 도입된 개념이 비동기(Asynchronous)이다.

비동기는 특정 작업의 완료를 기다리지 않고 다른 작업을 동시에 수행할 수 있게 한다.

비동기는 메인 스레드가 작업을 다른 곳에 인가하여 처리되게 하고, 그 작업이 완료되면 콜백 함수를 받아 실행하는 방식으로, 쉽게 말해 작업을 백그라운드에 요청하여 처리되게 하여 멀티로 작업을 동시에 처리하는 것이다.

자바스크립트는 싱글 스레드 언어인데 어떻게 비동기가 가능한 것일까?

자바스크립트를 실행하는 콜 스택(Call Stack)은 싱글 스레드지만, 서버에게 리소스를 요청하거나 파일 입출력 혹은 타이머 대기 작업을 실행하는 Web APIs 들은 멀티 스레드이기 때문에 동시 작업 처리가 가능하기 때문이다.

Web API는 타이머, 네트워크 요청, 파일 입출력, 이벤트 처리 등 브라우저에서 제공하는 다양한 API를 포괄하는 API의 총칭이다. 브라우저마다 다르겠지만, 크롬 브라우저 일 경우 Web API는 멀티 스레드로 구현되어 있다.

다만 성능 향상을 위해 비동기 처리를 이용할 때 주의해야 할 점이 있다. 비동기는 요청한 작업의 완료 여부를 기다리지 않기 때문에 다음 실행할 작업이 이전에 요청한 작업의 결과가 반드시 필요할 경우 문제가 생긴다.

따라서 자바스크립트의 Promise 객체는 이러한 한계점을 극복하기 위해 비동기 처리를 위한 전용 객체로서 탄생하였다. Promise는 비동기 작업의 성공 또는 실패와 그 결과값을 나타내는 객체이다.

하지만 프로미스도 완벽한 해결책은 아니다. 왜냐하면 Callback Hell이 있듯이 지나친 then 핸들러 함수의 남용으로 인한 Promise Hell이 존재하기 때문이다. 즉, 프로미스가 여러 개 연결되면 코드가 길어지고 복잡해질 수 있다는 것이다.

그래서 자바스크립트에는 async/await라는 문법이 또한 추가되었다. async/await는 프로미스를 기반으로 하지만, 마치 동기 코드처럼 작성할 수 있게 해준다.


참고 자료