JS 비동기 처리 방법들 (콜백 함수, 프로미스)

프로미스 배경

전통적으로 콜백 패턴을 사용하지만 이는 콜백 헬(callback hell)을 발생시켜 가동성을 나쁘게 하고, 비동기 처리 중 발생한 에러의 예외 처리가 곤란하며, 여러 개의 비동기 처리를 한 번에 처리하는 데도 한계가 있다.

ES6에서는 비동기 처리를 위한 또 다른 패턴으로 프로미스(Promise)를 도입했다. 프로미스는 전통적인 콜백 패턴이 가진 단점을 보완하며 비동기 처리 시점을 명확하게 표현할 수 있다는 장점이 있다.

콜백 패턴의 단점

비동기 함수는 비동기 처리 결과를 외부에 반환할 수 없고, 상위 스코프의 변수에 할당할 수도 없다. 따라서 비동기 함수의 처리 결과에 대한 후속 처리는 비동기 함수 내부에서 수행해야 한다. 이때 비동기 함수를 범용적으로 사용하기 위해 비동기 함수에 비동기 처리 결과에 대한 후속 처리를 수행하는 콜백 함수를 전달하는 것이 일반적이다. 필요에 따라 비동기 처리가 성공하면 호출될 콜백 함수와 비동기 처리가 실패하면 호출될 콜백 함수를 전달할 수 있다.

이 상황에서 콜백 함수를 통해 비동기 처리 결과에 대한 후속 처리를 수행하는 비동기 함수가 비동기 처리 결과를 가지고 또다시 비동기 함수를 호출해야 한다면 콜백 함수 호출이 중첩되어 복잡도가 높아지는 현상이 발생하는데 이를 콜백 헬(callback hell)이라고 한다.

콜백 패턴의 문제점 중에서 가장 심각한 것은 에러 처리가 곤란하다는 것이다. 에러가 호출자(caller) 방향으로 전파되기 때문이다. 예를 들어 setTimeout 함수로 콜백 함수가 에러를 발생시키도록 하면 catch 코드에서 캐치되지 않는다. 콜백 함수를 호출한 것은 setTimeout 함수가 아니고 이벤트 루프에 의해 콜 스택으로 푸시되어 실행되기에 콜백 함수가 발생시킨 에러는 catch 블록에서 캐치되지 않는다.

프로미스

Promise 생성자 함수를 new 연산자와 함께 호출하면 프로미스를 생성한다.

마이크로태스크 큐 (vs 태스크 큐)

마이크로태스크 큐(microtask queue/job queue)에는 프로미스의 후속 처리 메서드의 콜백 함수가 일시 저장된다. 콜백함수나 이벤트 핸들러를 일시 저장한다는 점에서 태스크 큐와 동일하지만 마이크로태스크 큐는 태스크 큐보다 우선순위가 높다.

카테고리:

업데이트:

댓글남기기