상세 컨텐츠

본문 제목

callback, promise, async/await 의 특징과 차이점

Javascript

by 리액트바오 2022. 10. 19. 13:19

본문

콜백 함수란

콜백 함수는 일반적으로 다른 함수의 인자(argument)로 전달되는 함수를 callback 함수라고 한다.

 

 

비동기와  콜백 함수

브라우저, node.js는 비동기 작업을 처리하기 위해서 callback 함수를 자주 사용하는데, 비동기 작업을 해결하기에는 이미 충분했지만, 콜백함수에는 한계가 있었다. 무슨 한계가 있었을까?

콜백 함수의 한계

코드 가독성 측면에서 문제가 많았다. callback은 함수에 담아서 사용해야 하기 때문에, 함수가 연속적으로 반복되어 직관적이지 않은 단점이 있는데 이를 "callback hell"이라고 부른다.  또한, callback이 인자로 전달되는 특성 때문에, 이게 callback인지 아닌지 눈으로 확인하기가 쉽지 않아서 개발자가 코드를 오작성할 확률이 높았다.

 

callback hell 예시

 

 

 

"callback hell"을 보완하기 위해 Promise 등장

"callback hell"을 해결하기 위해서 Promise가 새롭게 등장했는데, Promise는 비동기 코드를 간편하게 처리할 수 있게 도와주는 자바스크립트의 객체다. 즉, Promise는 단어 그대로 약속이다.  executor 콜백함수에서 요청한 데이터가 처리되는  대로 Promise 객체 (Promise의 인스턴스)의 result값으로 전달해 주겠다는 약속이다.

 

 

Promise 의 동작 방법

Promise는 Promise 인스턴스가 호출되면 해당 작업이 끝날 때 까지 기다려주기를 약속한다. 해당 작업은 성공일 수 있고, 실패일 수 있다.  Promise 클래스의 인스턴스를 생성할 때 자동으로 실행될 executor 라는 콜백함수를 전달해줘야 하는데, executor에는 또 다시 두가지 콜백함수를 전달해야 한다. executor에 전달해줘야 할 두 가지 콜백함수는 다음과 같다.

  • 작업이 성공한 경우 → resolve: 기능을 정상적으로 수행해서 마지막에 최종데이터를 전달해주는 함수
  • 작업이 실패한 경우 → reject: 기능을 수행하다가 중간에 문제(에러)가 발생하면 호출하게 될 함수

promise의 인스턴스가 생성되는 동시에 executor 콜백함수가 실행되며 제대로 실행이 되었을때 최종적으로 resolve함수로 전달된 인자가 인스턴스의 결과값으로 전달된다. 반대로 실행 중에 에러가 발생하면 reject함수로 전달된 인자가 인스턴스의 결과값으로 전달된다. 프로미스의 인스턴스는 항상 다음 세가지 중 하나의 상태(state)를 가진다.

  • pending(대기): 이행되거나 거부되지 않는 초기 상태
  • fulfilled(이행): 연산이 성공적으로 완료됨.
  • rejected(거부): 연산이 실패함.

Promise.prototype.then() Promise.prototype.catch() 메소드는 프로미스를 리턴하기 때문에 Promise Chaining이 가능하다.

 

 

하지만 Promise에도  한계가 있었다.

Promise 역시 하나의 비동기 작업을 처리하기에는 무리가 없었으나, 연속되는 비동기 작업이 순서대로 작동되어야 하는 경우 callback hell 처럼 "promise hell"이 발생하였기 때문에, .then으로 chaining을 하기 보다는 기존에 쓰던 함수처럼 쉽게 작성하고 싶었다.

 

Promise의 한계를 보완하기 위한  Async/Await 의 등장

그래서 async/ await이 생기게 되었는데, 마치 동기적으로 작동하는 것처럼 Promise를 좀 더 쉽게 다룰 수 있게 만들어졌다.  async / await 키워드만 적절히 사용하면 기존 함수를 작성하는 문법을 그대로 살릴 수 있다.

async 함수를 실행하면 함수내 리턴값의 여부에 상관없이 Promise가 리턴 되며, 함수 내의 리턴값은 async가 출력하는 Promise의 result값으로 전달된다. await 키워드는 async 함수 내에서만 사용가능하며, await키워드로 비동기 코드를 처리하면 응답이 올때까지 코드 읽기를 멈췄다가 요청이 오고 나서야 다음 코드를 실행한다. await 키워드로 실행된 코드는 Promise가 아닌 Promise의 result에 담긴 값을 반환한다. 

 

 

 

사진출처: https://medium.com/@kyle_seongwoo_jun/%EC%BD%9C%EB%B0%B1-%ED%97%AC%EC%9D%84-async-await%EB%A1%9C-c-taskcompletionsource-9433dfd61eec 

 

 

콜백 헬을 async/await로, C# TaskCompletionSource

JavaScript에 Promise가 있듯이 C#에는 Task가 있다.

medium.com

 

관련글 더보기