비동기 프로그래밍을 주로 사용하는 Node는 어떤 작업이 먼저 완료될지 알 수 없다.
이벤트 주도 방식 때문에 콜백 함수 자주 사용
-> 순차적인 작업을 위해서 콜백 안에, 콜백 안에, 콜백 안에,,,
결국, Callback Hell 유발!
특정 함수의 파라미터로 전달되는 콜백 함수
함수의 흐름을 동기적으로 제어하기 위해 연속적으로 콜백 함수 활용 시 콜백 헬에 빠지게 됨
코드 가독성이 매우 떨어지고, 유지보수 어려워짐
콜백 헬을 피하기 위해 흐름 제어가 필요하다.
흐름 제어의 종류: Promise Async
JS ES6부터 공식적으로 포함된 흐름 제어 패턴, 비동기 작업을 순차적으로 실행하거나, 병렬로 진행, 내부적 예외처리 구조가 탄탄하여 오류 처리가 가시적으로 관리 가능
Promise 상태
Pending : 동작 완료 전 (성공, 실패 전) 수행 중인 상태
Fulfilled : 비동기 동작 성공
Rejected : 비동기 동작 실패
Settled : 성공이건 실패이건 일단 결론이 난 상태
const promise1 = function (condition) { return new Promise((resolve, reject) => { if (condition) { resolve("true"); } else { reject("false"); } });
const promise2 = new Promise((resolve, reject) => { if (condition) { resolve("true"); } else { reject("false"); } });
동작에 대한 결과를 올바르게 줄 수 있으면 resolve 함수 호출
동작을 실패했으면 reject 함수 호출
promise1(condition).then( (message) => { console.log(message); }, (error) => { console.log(error); });
then API
비동기 작업 완료 시 결과에 따라 함수 호출
첫번째 파라미터: 성공 시 호출할 함수
두번째 파라미터: 실패 시 호출할 함수
promise2(false) .then((message) => { console.log(message); }) .catch((error) => { console.log(error); });
catch API
체이닝 형태로 연결된 상태에서 비동기 작업이 중간에 에러가 났을 때 != .then(null, () => {})
ES7에서 새롭게 지원하는 문법
기존 async나 promise를 사용하지 않고도 콜백 지옥 효과적으로 해결
Async/Await을 사용하려면 Promise 함수가 사용됨 (모든 async 함수는 암묵적으로 promise를 반환하고 promise가 함수로부터 반환할 값을 resolve)
비동기 코드의 겉모습과 동작을 좀 더 동기 코드와 유사하게 만들어줌
await
Promise를 기다림(성공 / 실패 기다림)
async로 정의된 내부에서만 사용
let asyncFunction1 = (message) => new Promise((resolve) => { setTimeout(() => { console.log("func1", message); resolve("func1"); }, 1000); }); let asyncFunction2 = (message) => new Promise((resolve) => { setTimeout(() => { console.log("func2", message); resolve("func2"); }, 500); }); function notAsyncMain() { asyncFunction1("hello") .then((data) => { console.log(data); return asyncFunction2("world"); }) .then((data) => { console.log(data); }); } async function asyncMain() { let data = await asyncFunction1("hello"); console.log(data); data = await asyncFunction2("node"); console.log(data); }
notAsyncMain 과 asyncMain은 같은 결과를 보여줌