Node.js 흐름 제어

김현우·2021년 9월 9일
0

흐름 제어

CallBack Hell

비동기 프로그래밍을 주로 사용하는 Node는 어떤 작업이 먼저 완료될지 알 수 없다.

이벤트 주도 방식 때문에 콜백 함수 자주 사용
-> 순차적인 작업을 위해서 콜백 안에, 콜백 안에, 콜백 안에,,,

결국, Callback Hell 유발!

특정 함수의 파라미터로 전달되는 콜백 함수

함수의 흐름을 동기적으로 제어하기 위해 연속적으로 콜백 함수 활용 시 콜백 헬에 빠지게 됨

코드 가독성이 매우 떨어지고, 유지보수 어려워짐

콜백 헬을 피하기 위해 흐름 제어가 필요하다.
흐름 제어의 종류: Promise Async

Promise

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 함수 호출

Promise 실행

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, () => {})

Async / Await

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);
}

notAsyncMainasyncMain은 같은 결과를 보여줌

profile
두려워 말라, 놀라지 말라, 굳세게 하리라

0개의 댓글