프로미스

서지우·2023년 7월 19일
0

JavaScript

목록 보기
11/11

동기와 비동기

동기

동기는 요청을 보낸 후 응답(결과물)을 받아야지만 다음 동작이 이루어지는 방식을 말한다.
모든 일은 순차적으로 실행되며 어떤 작업이 수행중이라면 다음 작업은 대기하게 된다.


비동기

비동기로 처리하지 않고 동기적으로 구성을 하게 된다면 데이터를 받아오기까지 기다린 다음에 앱이 실행될 것이고 서버에 가져오는 데이터 양이 늘어날수록 앱의 실행속도는 기하급수적으로 느려진다.
데이터를 가져오기까지 앱이 대기하는 상태가 발생하게 된다. 이런 불편을 없애기 위해서 데이터를 수신하는 코드와 페이지를 표시하는 것과는 비동기적으로 처리를 해야한다.

자바스크립트에서 비동기 프로그래밍이 가능한 이유

자바스크립트는 싱글 스레드이지만, 브라우저에서는 이벤트 루프 덕분에 멀티 스레드로 동작하여 비동기 작업이 가능하다.
타이머함수(setTimeout), setInteraval, HTTP 요청, 이벤트 핸들러는 비동기 처리 방식으로 동작한다.


프로미스란?

콜백 함수의 단점을 보완하며 비동기 처리에 사용되는 객체를 프로미스(Promise)라 한다. 

객체이기 때문에 생성자 함수를 호출하여 인스턴스화할 수 있다. 프로미스의 생성자 함수는 resovle와 reject함수를 인자로 전달받는 콜백함수를 인자로 전달받는다. 인자로 전달받은 콜백 함수를 내부에서 비동기 처리한다.

콜백 : 나중에 사용할 함수를 미리 넣어놓는 것
콜백을 이용해서 통신 이후 응답이 오면 코드를 실행하게 만듬 -> 비동기

resolve 함수가 호출 된경우 성공된 상태이고, reject 함수가 호출 된 경우 실패 상태이다.

이점
- 비동기 처리 시점을 명확하게 표현할 수 있다.
- 연속된 비동기 처리 작업을 수정, 삭제, 추가하기 편하고 유연하다.
- 비동기 작업 상태를 쉽게 확인할 수 있다.
- 코드의 유지 보수성이 증가한다.

예를들어,
동기
- 판매자가 택배상자에 상품넣기
- 구매자가 택배상자 받기
- 구매자가 택배상자 열기
- 구매자가 상품 꺼내기

프로미스 : 상품이 나중에 들어오는 택배상자
- 판매자가 택배상자를 구매자에 보냄
- 구매자가 택배상자를 받았으나 안에 상품이 없는 상태
- 상품이 없으면 안열림 / 상품이 있으면 자동으로 열림


후속 처리 메소드

then

- then 메소드는 두 개의 콜백 함수를 인자로 전달 받습니다.
- 첫 번째 콜백 함수는 성공(fulfilled, resolve 함수가 호출된 경우)시에 실행됩니다.
- 두 번째 콜백 함수는 실패(rejected, reject 함수가 호출된 경우)시에 실행됩니다.
- then 메소드는 기본적으로 프로미스를 반환합니다.

catch

- catch 메소드는 비동기 처리 혹은 then 메소드 실행 중 발생한 에러(예외)가 발생하면 호출됩니다.
- catch 메소드 역시 프로미스를 반환합니다.

실습 - s23.html

주석으로 설명..

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        const bool = false;

        // 프로미스
        const promise = new Promise((resolve, reject) => {
            // 프로미스 내에서 작업을 하고
            // 작업이 성공하면 resolve 실행 / 실패하면 reject실행

            setTimeout(() => {
                if (bool) {
                    resolve("작업성공");
                } else {
                    reject("작업실패");
            }
            }, 3000);

        });

        promise
        // resolve로 결과가 나오면 then안에 있는 콜백함수가 실행된다
        .then((value) => {
            console.log(value);
        })
        // reject로 결과가 나오면 catch안에 있는 콜백함수가 실행된다
        .catch((value) => {
            console.log(value);
        })
        // 어떻게 결과가 나오든 무조건 실행된다
        .finally(() => {
            console.log("finally");
        });

        console.log("프로미스 작성 이후 코드 실행");
    </script>
</body>
</html>

실행결과
boolean 값이 false니까!!
3초 후에 작업실패가 실행된다.


실습 - s23Quiz.html

주석으로 설명

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // 할일
        // 세탁기 돌리기1 = 세탁 끝나면 빨래감 널기2 - 라면먹기3
        // 세탁기 돌리기를 Promise
        // 세탁기 돌리기 시작할 때 "세탁을 시작합니다" 메시지 출력 1
        // 세탁기 다돌아가면 "빨래감을 널었습니다" 메시지 출력 3
        // 라면 다먹었으면 "라면을 먹었습니다." 메시지 출력 2

        // 동기
        console.log("세탁을 시작합니다.");
        console.log("빨래감을 널었습니다.");
        console.log("라면을 먹었습니다.");
        const 빨래시간 = 2000;
        const 세탁기상태 = false;
        
        // 비동기
        console.log("세탁을 시작합니다.");
        new Promise((resolve, reject) => {
            if (세탁기상태) {
                setTimeout(() => {
                    resolve("빨래완료")
                }, 빨래시간);
            } else {
                reject("세탁기고장");
            }
        }).then(() => {
            console.log("빨래감을 널었습니다.");
        }).catch(() => {
            console.log("세탁기가 고장났습니다.");
        });
        console.log("라면을 먹었습니다.");

        // const promise = new Promise((resolve, reject) => {
        //     setTimeout(() => {
        //         if (Bool) {
        //             resolve("세탁기를 돌립니다."); 
        //         } else {
        //             reject("")
        //         }
        //     }, 3000);
        // });
        // const promise1 = new Promise((resolve, reject) => {
        //     setTimeout(() => {
        //         if (Bool) {
        //             resolve("빨래감을 널었습니다.."); 
        //         } else {
        //             reject("")
        //         }
        //     }, 3000);
        // });

        // promise
        // .then((value) => {
        //     console.log(value);
        // })
        // // reject로 결과가 나오면 catch안에 있는 콜백함수가 실행된다
        // .catch((value) => {
        //     console.log(value);
        // })
        // // 어떻게 결과가 나오든 무조건 실행된다
        // .finally(() => {
        //     console.log("라면을 다 먹었습니다.");
        // });

        

    </script>
</body>
</html>

실행결과
세탁기상태를 false로 줬을때
(비동기 방식이라 순서대로 기다리지 않고 '라면을 먹었습니다.'가 나오고 '세탁기가 고장났습니다'가 실행됨)

세탁기상태를 true로 줬을때


참고자료

https://www.youtube.com/watch?v=m0icCqHY39U

profile
미래가 기대되는 풀스택개발자 공부 이야기~~

1개의 댓글

comment-user-thumbnail
2023년 7월 19일

정말 유익한 글이었습니다.

답글 달기