동기와 비동기를 이해하기 위해서 JavaScript에 대해서 짚고 넘어가자.
자바스크립트란 싱글스레드기반의 언어로 동기적으로 실행된다.
여기서 싱글스레드란 말 그대로 한번에 하나의 작업만을 수행함을 의미한다.
하나의 작업이 진행되는 동안 다른 작업은 중간에 끼어 들 수 없으며,
그 작업이 끝날 때 까지 다른 작업들은 대기하고 있다가 그 작업이 끝날 때 비로소 작업을 수행할 수 있다.
이런식으로 자바스크립트는 동기적으로 실행됨에 따라 모든 작업들이 순서대로 이루어진다는 장점이 있는 반면에, 동기적으로 실행되다 보니 그 작업이 끝날 때까지 무조건 기다려야 한다는 단점 또한 있다.
자바스크립트는 웹쪽에서 많이 사용되는데 만약 동기적인 방식으로만 작동이 된다면
클라이언트는 무작정 기다릴 수 밖에 없을거다.
하나의 버튼을 클릭하고 그 버튼이 실행될 때 까지 무제한 기다림...
이러한 문제를 해결할 수 있는 방법이 바로 비동기 방식이다.
그렇다면 여기서 동기와 비동기에 대해 다시 한 번 정리하고 넘어가자.
동기(Synchronous) :
동시에 일어난다는 의미로 요청이 일어나면 그 요청이 끝날 때 까지 다음 작업은 대기
비동기(Asynchronous) :
동시에 일어나지 않으며, 특정 작업을 수행할 때 작업의 결과를 기다리지 않고 다음 작업을 수행
콜백함수는 말 그대로 다시 전화를 하라는 의미이다.
비동기 콜백함수로 어떠한 요청을 할 때 콜백함수의 파라미터로 다른 함수를 전달하여 콜백함수를 실행할 수 있고, 첫 번째 콜백함수가 실행되는 동안 다음 코드들도 실행이 된다.
이처럼 콜백함수는 한번에 여러 작업들이 실행 된다는 장점도 있지만,
이 콜백함수가 파라미터로 계속 이어지면 콜백지옥(Callback Hell)이 발생된다.
콜백지옥은 순차적으로 처리해야하는 이벤트들을 콜백함수 안에 넣어주는 방식이다.
그리고 콜백함수의 코드 중 잘못된 코드가 작성된다면 그 지점부터 콜백함수를 전부 수정해야하는 상황이 올 수 있으며, 만약 에러처리를 해야한다면 모든 콜백에서 각각 에러를 처리해주어야 한다.(에러핸들링)
이러한 콜백지옥의 해결방안(?)으로 나온 또 다른 방식이 바로 Promise방식이다.
Promise는 우선 객체(Object)이며, 결과값은 성공(resolve)와 실패(reject)로 나온다.
◆ 형식 : new Promise(resolve, reject)
resolve : 작업이 성공했을 때
reject : 작업이 실패했을 때
◆ Promise 인스턴스에는 어떤 메서드가 존재하는가?
.then() : 새로운 Promise 객체를 반환
.catch() : Promise의 에러를 반환
◆ Promise의 세 가지 상태
대기(Pending) : 아직 결과 값이 반환되지 않은 진행 중인 상태
이행(Fullfilled) : 처리 완료(성공)
실패(Rejected) : 처리 실패 혹은 오류
◆ Promise Chaining(프로미스 체이닝)
프로미스 체이닝은 콜백함수의 콜백지옥처럼 .then()을 이용하여 계속 체이닝을 하는 것으로
이 때, .then()은 새로운 프라미스 객체를 반환한다.
◆ Promise.all([])
인자로 배열을 받고 배열의 인자가 동시에 실행된다는 점이 Promise실행과의 차이점이다.
(Promise Chaining과 Promise.all은 실행순서가 다르다는 것을 명심!)
Promise.all은 전부 성공해야 하며, 하나라도 실패 시 결과는 reject가 반환된다.
비동기 방식 중 제일 가독성이 좋으며 깔끔한 방법인 Async&Await 방법이다.
함수 앞에 Async를 붙여야 하고 비동기로 처리를 해야하는 부분에 Await를 붙여야한다.
Async&Await는 Promise로 객체를 반환한다.
여기서 중요한 점은 await 키워드를 어디에 붙여야 하는가인데
아무곳에 붙이는게 아닌! Promise로 리턴되는 객체에 붙여야 한다!