콜백(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
'자바스크립트' 카테고리의 다른 글
DOM과 BOM (0) | 2021.07.16 |
---|---|
자바스크립트 Scope와 Closure (0) | 2021.07.14 |
[JS] this와 bind (0) | 2021.07.10 |
[JS] Hoisting과 변수 선언 3가지 방법(var, const, let) (0) | 2021.06.30 |