본문 바로가기

자바스크립트

자바스크립트 비동기 처리 -callback, promise, async/await

콜백(Callback)


  • 인자로 받아들인 함수를 다시 호출하는 기능을 callback
  • 즉 시간이 오래걸리는 작업이 있을 때 이 작업이 완료된 후에 처리해야 할 일을 콜백으로 지정하면 해당 작업이 끝났을 때 미리 등록한 작업을 실행하도록 할 수 있음
  • callback hell : 콜백함수가 늘어나면 늘어날 수록 코드의 깊이가 늘어나 더이상 헤어날 수 없다는 자조성 용어
  • 코드 관점에서 콜백함수는 중첩으로 들여쓰기(nesting)가 반복되어 가독성이 떨어짐
  • 각 콜백함수에서 에러 핸들링을 해주어야 함, 에러처리를 하지 않으면 어디서 에러가 발생한지 알기 어려움

콜백의 문제

  • 신뢰성 : 콜백은 제어권의 주체가 바뀜, 콜백 내부에서 예외처리는 가능해도 비동기요청-콜백함수 흐름은 제어가 어려움
  • 이에 Promise가 등장, 비동기 요청 수행에 대한 결과값을 가지고 결과값을 콜백에 전달해줌
  • 가독성
  • Generator로 해결했으나 후에 async/await 등장(promise의 syntatic sugar)

promise


  • Promise 객체는 new 키워드로 생성하고, 4개의 상태 값을 가짐, 상태값은 크게 Pending과 Settled로 나누며,Settled은 다시 fulfilled과 Rejected로 나뉜다.(진행중인 상태, 성공, 실패, 결과값이 반환된 상태)
  • Promise는 작업이 끝난 후 실행할 함수를 제공하는 것이 아니라 Promise 자체 메소드인 .then()을 호출.
  • 함수를 인자로 받고, 함수는 다시 resolve 와 reject를 함수로 받음(각각 then, catch 메소드 인자로 들어감)
  • Promise에서는 작업이 실패하였을 경우 자동으로 .catch() 메소드가 호출. 따라서 callback과 같이 함수 호출 중간에 if-else를 사용하는 것이 아닌 .catch()로 한번에 해결할 수 있는 장점이 있음
  • then 과 catch 메소드는 다시 promise 객체를 반환해 chaining이 가능함 -> 하나라도 에러 발생 시 catch 로 넘어감
  • 에러를 잡을 때 몇번째에서 발생했는지 알아내기도 어렵고 특정 조건에 따라 분기를 나누는 작업도 어렵고, 특정 값을 공유해가면서 작업을 처리하기 어려움

async, await


  • Async와 Await을 사용하려면 우선 사용할 함수 앞에 async라는 키워드를 붙여 사용해야 하며 선언된 async 함수 안에서만 await 키워드를 사용할 수 있음(promise를 반환하는 비동기 처리 함수 앞에 await를 붙여줌)
  • function 앞에 async 키워드가 붙으면 해당 함수는 항상 Promise를 반환
  • await은 함수의 작업이 끝나고 결과값을 반환할 때까지 대기하게 되며 결과 값이 리턴된다면 다음 작업으로 넘어감

참고


호출스택(Call stack)

  • 함수가 호출되는 순서대로 쌓이는 스택, 함수 리턴 시 호출 스택 맨 위에 있는 함수를 끄집어냄, 함수라기 보단 함수의 실행 문맥
  • 코드가 실행될 때 호출 스택이 쌓이며 호출 스택의 각 항목을 스택 프레임이라 함
  • 자바스크립트는 하나의 콜 스택을 사용하며 메소드가 실행될 때 콜스택에 하나의 프레임이 생기고 push되고 끝나면 해당 프레임은 pop 됨
  • 함수를 실행하면 해당 함수의 기록을 스택 맨 위에 추가(Push)
  • 함수를 결과 값을 반환하면 스택에 쌓여있던 함수는 제거(Pop)
  • 메모리 힙(Memory Heap) : 객체(동적으로 생성된 객체)는 힙, 대부분 구조화되지 않은 메모리 영역에 할당
  • 스택 오버플로우 : 이름 그대로 스택의 사이즈를 초과 했을 때 발생하는 오류, 종료 조건 없는 재귀함수의 경우 자신을 계속해서 호출해 함수가 계속 쌓여 오류 발생
  • Heap Overflow: 힙 영역에서 할당 된 영역의 경계선 밖으로 넘어갈 때 발생(매우 큰 데이터를 동적으로 할당하려 할 때)
  • 자바스크립트의 경우 단일 스레드에서 코드를 실행, 단일 호출 스택
  • 콜백(함수)의 경우 콜백 큐에 쌓임
  • 이벤트 큐(Event Queue) : 처리할 메시지 목록과 실행할 콜백 함수들의 리스트
  • 이벤트 큐는 대기하다가 스택이 텅 비는 시점에 이벤트 루프를 돌림(스택에 넣음).
  • 스택에 대한 모든 호출이 반환될 때까지 메세지 폴링(polling) 및 처리가 중지. 동기식 함수 호출은 이와 반대로 새 호출 프레임을 스택에 추가

이벤트 루프(event loop)


  • 자바스크립트 엔진은 Call stack, Event queue, Heap 으로 나뉘고 Event loop가 이벤트 큐에 들어가는 task를 관리함
  • 이벤트 루프의 기본 역할은 큐와 스택, 두 부분을 지켜보다가 스택이 비는 시점에 콜백을 실행시켜 주는 것
  • 이벤트루프는 호출 스택과 콜백 큐를 계속 주시하고 있다 호출 스택이 비어있으면 순서대로 콜백큐의 콜백 함수를 호출 스택으로 집어 넣음
  • 자바스크립트 비동기 참고 블로그

화살표함수(Arrow function)

  • 간결하게 함수 표현
  • 화살표 함수는 항상 익명
  • 자신의 this, arguments, super 그리고 new.target을 바인딩하지 않아 생성자로는 사용할 수 없음
  • 상위 스코프 this

'자바스크립트' 카테고리의 다른 글