ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JavaScript]비동기 프로그래밍
    JavaScript 2022. 6. 17. 14:23
    728x90

    비동기(Asynchronous) vs 동기(Synchronous)

    예시로 쉽게 이해해보고 넘어가겠습니다.

    A와 B는 집안일을 해야합니다.

    1) 빨래 돌리기
    1-1) 빨래 널기
    2) 이불, 배게 털기
    3) 욕실 청소
    4) 피규어 정리

    A의 작업 현황

    1) 빨래 돌리기(진행 중)
    1-1) 빨래 널기
    2) 이불, 배게 털기
    3) 욕실 청소
    4) 피규어 정리

    B의 작업 현황

    1) 빨래 돌리기(진행 중)
    1-1) 빨래 널기
    2) 이불, 배게 털기(완료)
    3) 욕실 청소(완료)
    4) 피규어 정리(진행 중)

    A는 빨래를 돌려놓고 쉬고 있고 B는 빨래를 돌려놓고 2, 3을 완료 후 4를 하고 있습니다.

    이때 B는 A에게 넌 왜 쉬어?라고 묻자

    A는 아.. 1-1) 빨래 널기를 해야 하는데 1) 빨래 돌리기가 아직 진행 중이잖아라고 답합니다. 이때 A는 동기적으로 B는 비동기적으로 집안일을 하고 있는 것입니다.

    또 다른 예를 들어보겠습니다.

    동기

    1) 짜장면 만들기
    2) 짜장면 배달
    3) 짜장면 먹기(손님)
    4) 짜장면 그릇 회수

    동기적으로 1~4가 이루어진다면 배달부는 손님이 짜장면을 다 먹을때 까지 기다렸다가 그릇을 회수해야합니다.

    비동기

    1) 짜장면 만들기
    2) 짜장면 배달
    3) 짜장면 먹기(손님)
    4) 짜장면 그릇 회수

    비동기적으로 1~4가 이루어진다면 배달부는 배달 후 다른일을 하다가 손님이 다 먹고나서 회수를 할 수 있겠죠?

    주문자와 배달부가 서로 다른 쓰레드에서 일을 한다고 생각할 수 있습니다.

    프로그래밍이 비동기로 일을 한다는 건 쓰레드나 프로세스가 여럿 돌고 있다는 말도 되는겁니다.

    멀티태스킹이 구현되고 있는 거라고 볼 수 있습니다.

    JavaScript의 비동기

    하지만 여기서 의문인 점은 자바스크립트는 싱글 쓰레드인 언어라는 것 입니다.

    javascript는 javascript 엔진 뿐 아니라 Web API 엔진도 함께 동작합니다.

    Web API에선 타이머를 사용하는 작업, AJAX로 http 요청, 파일에서 데이터 읽어오기 등 시간을 소요하는 작업을 수행합니다.

    function asyncBlackBeanEaters(name) {
        console.log(`${name}에게 배달`);
    
        http.get("http://localhost:3000/eat-noodle-rand",
            function(){
                console.log(`${name} 식사 완료`);//eventRoop
            }
        );
    }
    
    let eaters = ["유민상", "김준현", "문세윤", "김민경", "돈스파이크"];
    for(let i=0; i<eaters.length; i++) {
        asyncBlackBeanEaters(eaters[i]);
    }

    위 코드의 결과는 다음과 같습니다.

    유민상에게 배달
    김준현에게 배달
    문세윤에게 배달
    김민경에게 배달
    돈스파이크에게 배달
    문세윤 식사 완료
    김준현 식사 완료
    돈스파이크 식사 완료
    김민경 식사 완료
    유민상 식사 완료

    실제로 비동기로 대학교에서 한 학생의 고등학교 3학년 당시 수학 교사를 찾는 코드를 보겠습니다.

    function 고3_수학교사_찾기(학생_학번) {
        학생정보_조회(학생_학번,
            function(학생_정보) {
                const 학생_주민번호 = 학생_정보['주민번호'];
                const 고교명 = 학생_정보['고등학교명'];
                고교_DB_주소_조회(고교명,
                    function(고교_DB_주소) {
                        고교시_수강수업_조회(고교_DB_주소, 학생_주민번호,
                            function(수강과목_일람) {
                                let 학생_고3_수업코드 = 수강과목_열람["고3수학"];
                                수업정보_조회(학생_고3_수업코드,
                                    function(수업정보) {
                                        console.log(`담당교사: ${수업정보[교사명]}`)
                                    })
                            })
                    })
            })
    }
    • 가독성도 떨어지고 실수 위험도 굉장히 높습니다.(콜백 지옥)

    이러한 문제를 해결하기위해 JavaScritp는 ES6부터 Promise라는 걸 도입했습니다.

    Promise

    • then을 통해 꼬리를 무는 체이닝 방식으로 순차적으로 처리가 가능하다.
    • polyfill등의 라이브러리 없이는 IE(Internet Explore)에선 동작하지 않습니다.
    학생정보_조회_Promise("12345")
    .then(function(학생_정보) {
        const 학생_주민번호 = 학생_정보['주민번호'];
        const 고교명 = 학생_정보['고등학교명'];
        return 고교_DB_주소_조회_Promise(학생_주민번호, 고교명);
    })
    .then(function(학생_주민번호_AND_고교_DB_주소) {
        return 고교재학시_수강수업_조회_Promise(
            학생_주민번호_AND_고교_DB_주소[0],
            학생_주민번호_AND_고교_DB_주소[1]
        )
    })
    .then(function(수강과목_일람) {
        const 학생의_고3수학_수업코드 = 수강과목_일람["고3수학"];
        return 수업정보_조회_Promise(학생의_고3수학_수업코드);
    })
    .then(function(수업정보) {
        console.log(`담당교사: ${수업정보['교사명']}`);
    })

    Promise를 통해 한 층 가독성은 좋아졌지만 여전히 복잡합니다.

    그래서 JavaScript는 ES7부터 Async/Await라는 걸 도입했습니다.

    Async/Await

    • 함수 앞에 async를 붙이면 비동기 작업을 마치 동기 작업처럼 작성할 수 있게 된다.
    • await을 앞에 붙이면 그 줄의 코드가 모두 완료 될 때 까지 다음 작업을 하지 않는다.
    async function 고3시_수학교사_찾기_Promise(학생_학번) {
    
        const 학생_정보 = await 학생정보_조회_Promise(학생_학번);
    
        const 고교_DB_주소 = await 고교_DB_주소_조회_Promise(학생_정보["고교명"]);
    
        const 수강과목_일람 = await 고교시_수강수업_조회_Promise(학생_정보["주민번호"], 고교_DB_주소);
    
        const 수업정보 = await 수업정보_조회_Promise(수강과목_일람["고3수학"]);
    
        console.log(`담당교사: ${수업정보["교사명"]}`);
    }
    
    고3시_수학교사_찾기_Promise("012345");
    • 내부 동작은 비동기적 작업이지만 동기 코드처럼 쉽고 직관적이게 작성할 수 있다.

    참고

    https://www.yalco.kr/21_async/

    728x90

    'JavaScript' 카테고리의 다른 글

    연산자(JavaScript)  (0) 2022.06.27
    데이터 타입(js)  (0) 2022.06.22
    [JavaScript] 메모리 관리, GC(가비지 컬렉션)  (0) 2022.06.20
    표현식과 문(javascript)  (0) 2022.06.16
    변수(js)  (0) 2022.06.15

    댓글

Designed by Tistory.