이미지 출처 : https://evan-moon.github.io/2019/09/19/sync-async-blocking-non-blocking/
자바스크립트에서 비동기 처리는 왜 필요할까?
만약 서버로부터 데이터를 받아올 때 비동기로 처리하지 않고 동기적으로 이를 구성한다면 데이터를 받아 오기까지 기다린 다음 브라우저가 실행이 될 것이다.
동기적으로 처리된다면 위와 같은 로딩 화면을 자주 마주쳐야 할 것이다.
→ 이런 불편을 없애기 위해 데이터를 수신하는 코드와 페이지를 표시하는 것을 비동기적으로 처리를 한다. 이 때 Javascript에서는 콜백 함수를 이용한다.
콜백함수(Callback function) : 나중에 호출할 함수, 어떤 이벤트가 발생한 후 수행될 함수
- 콜백은 자바스크립트에서 비동기 동작을 처리하는 좋은 방법이다.
- 콜백함수는 문법적 특징을 가지고 있는 것이 아니라, 호출방식에 의한 구분이다.
사용자 이벤트 처리
브라우저 화면에서 발생하는 사용자의 이벤트는 예측이 불가능하다.
따라서 이런 화면이벤트를 관리담당하는 녀석에게 우리는 특정이벤트가 발생할 때 호출을 원하는 내용을 callback 함수에 전달하게 된다.
네트워크 응답 처리
화면단에서 서버에게 요청을 보냈을 때, 그 응답이 언제 올지 알 수 없다.
따라서 이런 서버에 대한 응답처리 등도 비동기적으로 처리해야 한다.
의도적으로 시간 지연을 사용하는 기능(알람 등)
그러나 위와 같이 콜백 함수 연달아서 사용하다보면 의도하지 않은 콜백 지옥 현상이 나타날 수 있다.
콜백 지옥
: 콜백 함수를 익명 함수로 전달하는 과정이 반복되어 코드의 들여쓰기 수준이 깊어지는 현상.
이러한 콜백 지옥은 가독성이 떨어지고 코드 수정이 어렵다는 단점이 있다. 이러한 콜백 지옥을 탈출하기 위해서 Promise와 Async + Await가 사용된다.
프로미스
: 자바스크립트에서 제공하는 비동기적 이벤트를 간편하게 처리할 수 있도록 도와주는 객체이다.(Object).
const promise = new Promise((resolve, reject) => {
// code 작성
// Promise는 Promise 생성자 함수를 통해 인스턴스화하여 사용하고,
// 비동기 작업을 수행할 콜백 함수(resolve, reject)를 인자로 받는다.
});
프로미스를 사용할 때 알아야 하는 가장 기본적인 개념으로 프로미스의 상태(states)가 있다. 여기서 말하는 상태란 프로미스의 처리 과정을 의미하고, new Promise()로 프로미스를 생성하고 종료될 때까지 3가지 상태를 갖는다.
.then
then 메소드는 두 개의 콜백 함수를 인자로 전달 받는다. 첫 번째 콜백 함수는 성공(fulfilled, resolve 함수가 호출된 상태) 시 호출되고 두 번째 함수는 실패(rejected, reject 함수가 호출된 상태) 시 호출된다.
.catch
예외(비동기 처리에서 발생한 에러와 then 메소드에서 발생한 에러)가 발생하면 호출된다.
.finally
resolve, reject, 예외로 발생한 error 등 상관 없이 모든 과정이 종료되었을 때 호출된다.
function1()
.then(
resolve(){}, // promise의 state = fulfilled일 때 resolve콜백 함수 동작.
reject(){}) // promise의 state = rejected일 때 reject콜백 함수 동작.
.catch(function error(){}) // 비동기적인 일 처리 중 Error 발생 시 해당 error 콜백 함수 동작.(state = rejected)
.finally(function final(){}); // function1의 모든 비동기적 과정이 종료된 후 final 콜백 함수 동작.
비동기 함수의 처리 결과를 가지고 다른 비동기 함수를 호출해야 하는 경우, 함수의 호출이 중첩(nesting)이 되어 복잡도가 높아지는 콜백 헬이 발생한다. 프로미스는 후속 처리 메소드를 체이닝(chainning)하여 여러 개의 프로미스를 연결하여 사용할 수 있다. 이로써 콜백 헬을 해결한다.
function1()
.then(() => function2())
.then(() => function3())
.then(() => function4()) // 이렇게 후속 처리 메소드를 체이닝할 수 있다.
.catch(() => error())
.finally(() => final())
async function promise() { // function 앞에 async를 붙이면 promise가 반환된다.
await function(); // await를 적으면 비동기적인 처리가 모두 완료될때까지 기다렸다가 완료되면 함수가 동작한다.
return result;
}
https://velog.io/@kimdlzp/%EC%BD%9C%EB%B0%B1callback
https://joshua1988.github.io/web-development/javascript/promise-for-beginners/
https://dev.to/yatharth1706/promises-4a0
https://poiemaweb.com/es6-promise