Javascript-비동기 프로그래밍

hotbreakb·2022년 6월 25일
0

javascript

목록 보기
4/5
Synchronous(동기)코드가 순서대로 실행된다.
Asynchronous(비동기)실행되는 데 순서가 없다.

자바스크립트에서는 함수가 여러 번 호출될 때 순서대로 실행되지 않는다. 시간이 오래 걸리는 작업이 끝날 때까지 기다리는 것은 매우 비효율적이기 때문에 빨리 끝낼 수 있는 것부터 먼저 끝낸다. 이것이 🙈비동기 처리🙉이다.

비동기 어떻게 동작해?

function asyncBlackBeanTimer(seconds) {
    console.log("짜장면이 고객에게 배달");

    setTimeout(function () {
        console.log("고객 식사 완료"); ---> 콜백 함수
    }, seconds * 1000);

    console.log("배달부 떠남");
}

asyncBlackBeanTimer(2);

동기 프로그래밍을 하면 "짜장면이 고객에게 배달 ➡️ 고객 식사 완료 ➡️ 배달부 떠남"이 된다. 배달부는 고객이 짜장면을 다 먹을 때까지 기다리는 것이다. 이건 매우 비효율적이다. 차라리 이때 다른 배달 한 건 더 뛰는 게 낫다.

비동기 코드가 끝나면 내부에 있는 함수를 호출한다. 끝나면 불러줘! == 콜백 함수

콜백 함수

비동기 코드가 끝난 후 콜백 함수가 호출되면, 이 콜백 함수는 task queue에 올라간다. 이벤트 루프가 task queue에 있는 콜백 함수를 순서대로 실행한다.

콜백 지옥

짜장면을 만드는 순서를 확인해보자.

function asyncBlackBeanTimer(seconds) {
    setTimeout(function () {
        console.log("야채 썰기");
        setTimeout(function () {
            console.log("춘장 만들기");
            setTimeout(function () {
                console.log("고기 볶기");
                setTimeout(function () {
                    console.log("완성!");
                }, seconds * 1000);
            }, seconds * 1000);
        }, seconds * 1000);
    }, seconds * 1000);
}

asyncBlackBeanTimer(2);

"야채 썰기"가 끝나면 "춘장 만들기"를 호출한다. 이렇게 순서대로 동작하지만, 코드를 작성할 때도 헷갈리고 코드가 길어지면 무슨 동작을 하는 건지 쉽게 파악할 수 없다. 이런 코드는 ❌

Promise

콜백 지옥을 해결할 수 있는 방법으로 promise가 있다. 콜백 지옥보다는 쉽게 이해할 수 있다.

new Promise()로 프로미스를 생성한 후, 종료될 때까지 3가지 상태를 갖는다.

  • Pending(대기): 비동기 처리가 안 끝남
  • Fulfilled(이행): 비동기 처리가 완료되어 프로미스가 결과값을 반환해줌
  • Rejected(실패): 비동기 처리를 실패하거나 오류 발생함

Pending(대기)

new Promise()를 호출하면 대기 상태가 된다. new promise()를 호출할 때 콜백 함수를 선언할 수 있다. 콜백 함수의 인자는 resolvereject가 있다.

Fulfilled(이행 == 완료)

resolve()를 실행하면 이행된다. then()으로 resolve(여기 있는 값 == 처리 결과 값)을 받아올 수 있다.

Rejected(실패)

reject()를 실행하면 실패한다. catch()reject(여기 있는 값 == 실패한 이유)를 받아올 수 있다.

코드

...

const done = (seconds) => {
    return new Promise((resolve) => setTimeout(() => {
        resolve("완성!");
    }, seconds * 1000));
}

function asyncBlackBeanTimer(seconds) {
    cutting(1)
        .then(
            (text) => {
                console.log(text);
                return makeSource(1);
            })
        .then(
            (text) => {
                console.log(text);
                return roasting(2);
            })
        .then(
            (text) => {
                console.log(text);
                return done(1);
            })
        .then(
            (text) => {
                console.log(text);
            })
}

asyncBlackBeanTimer(1);

async/await

promise보다 조금 더 이해하기 쉽게 표현하기 위해서는 async/await를 사용한다. 비동기 함수를 동기 함수처럼 호출할 수 있다.

에러를 잡기 위해서는 try catch를 사용하면 된다.

코드

async function asyncBlackBeanTimer(seconds) {
    const result = await cutting(seconds); --> await 어어어어어어 wait!
    console.log(result);
    const result2 = await makeSource(seconds);
    console.log(result2);
    const result3 = await roasting(seconds);
    console.log(result3);
    const result4 = await done(seconds);
    console.log(result4);
}

참고 자료

profile
글쟁이 프론트 개발자, 헬렌입니다.

0개의 댓글