ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [TIL] Javascript 비동기 처리 방식
    Develope/Javascript 2020. 7. 7. 15:24

    javascript logo

    1. 비동기 방식

    비동기 방식이란, 특정 코드의 연산이 끝날 때까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하는 특성을 말한다.

    기다리는 과정에서 다른 함수를 호출할 수 있다.

    동기적 방식 : 작업이 끝날 때까지 다른 작업을 할 수 없다.

    동기적과 비동기적 방식을 밑의 그림처럼 표현할 수 있다.

     

    동기적은 1번이 끝날 때까지 2번을 시작하지 못한다. 1번이 끝나야 비로소 2번이 실행되고, 2번이 끝나야 3번을 시작할 수 있다.

    하지만 비동기는 1번이 끝나기 전에 2번의 코드를 실행할 수 있고, 2번이 끝나기 전에 3번을 시작할 수 있다.

    setTimeout() 함수가 대표적인 비동기 함수이다.

    setTimeout()은 코드를 바로 실행하지 않고 지정한 시간만큼 기다렸다가 로직을 실행하는 것을 말한다.

    예시를 한번 봐보자.

     

    setTimeout()

    비동기 처리에 대한 개념이 없으면 위의 코드 실행은 다음과 같다.

     - '첫번 째 console'

     - 1초 있다가 '두 번째 console (setTimeout 함수 내부)'

     - '세번 째 console.log

    하지만 결과는 다음과 같다.

     

    console.log

    첫 번째 console이 실행되고 두 번째 console은 1초 뒤 실행되니까 세 번째 console.log가 먼저 나온 뒤 setTimeout() 내부에 있는 console이 찍힌다.

    setTimeout() 역시 비동기 방식으로 실행되기 때문에 위와 같은 결과가 나타나는 것이다.

    2. 비동기 방식이 필요한 사례

     - Ajax Web API 요청 (서버 쪽에서 데이터를 받아올 때)

     - 파일 읽기 (서버 쪽에서 파일을 읽어와야 할 때)

     - 암호화/복호화

     - 작업 예약 (몇 초 후에 해야 되는 작업이 필요할 때)

    3. 비동기 방식의 종류

     - 콜백 함수

     - Promise 

     - async & await

    4. 콜백 함수

    ◎ 요새는 잘 사용하지 않는 비동기 함수이다.

    그 이유는, 콜백 함수로 처리하게 되면 비동기 작업이 많아질수록 코드가 난잡해지기 때문이다. 이걸 콜백 지옥이라 한다.

    간단히 숫자 n을 파라미터로 받아서 5번에 거쳐서 1초마다 1씩 더해서 구현하는 콜백 함수 코드를 봐보자.

     

    Callback 함수 code
    Callback console

    코드를 보면 정말 난잡하다. 1초마다 1씩 더해줘야 하기 때문에 콜백에 콜백에 콜백.....

    이렇게 비동기적으로 연달아서 해야 할 작업이 많아지면 작성하기도 어렵고 보기에 좋지 않다.

    그래서 나온 방법이 Promise이다. 

    5. Promise

    Promise는 자바스크립트 비동기 처리에 사용되는 객체이다. 

    프로미스는 주로 서버에서 받아온 데이터를 화면에 표시할 때 사용한다. 

    서버에다 데이터를 요청하는데 데이터를 받아오기 전에 데이터를 다 받아온 것처럼 화면에 데이터를 표시하려고 하면 오류가 발생한다.

    이와 같은 문제점을 해결하기 위한 방법 중 하나가 프로미스이다.

    5-1. Promise의 기본 문법

    const getData = new Promise((resolve, reject) => {
     // 구현 코드
    });

     - new Promise(); 메서드를 호출할 때 콜백 함수를 선언할 수 있고, 콜백 함수의 인자는 resolve, reject이다.

     - resolve성공할 때, reject실패할 때 호출한다.

     

    resolve : 성공했을 때

    resolve를 호출할 때 특정 값을 파라미터로 넣어주면, 이 값을 작업이 끝나고 나서 사용할 수 있는데, 작업이 끝나고 또 다른 작업을 해야 할 때에는 Promise 뒤에 .then( ) 키워드를 붙여서 사용하면 된다.

     

    reject: 실패했을 때

    reject를 호출 할 때는 .catch( ) 키워드를 사용하여 실패했을 시 수행할 작업을 설정할 수 있다.

    5-2. Promise 예제

    ◎ 위에서 콜백 함수를 사용한 예시를 Promise를 사용해서 구현해보자.

    추가로 증가된 숫자가 5 되면 에러 메시지가 나오게 해 보자.

     

    Promise code

    위의 코드처럼 then 내부에 넣은 함수에서 또 Promise를 리턴하게 되면, 연달아서 사용할 수 있다.

    비동기 작업의 개수가 많아져도 코드의 깊이가 깊어지지 않는 걸 확인할 수 있다.

    5-3. Promise 흐름

    Promise 흐름도

     - Pending(대기): 비동기 처리 로직이 아직 완료되지 않은 상태

     - Fulfilled(이행): 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태

     - Rejected(실패): 비동기 처리가 실패하거나 오류가 발생한 상태

    5-4. Promise의 단점

    ◎ Promise를 사용할 때 불편한 점이 있는데, 에러를 잡을 때 몇 번째에서 발생했는지 알아내기 어렵고, 특정 조건에 따라 분기를 나누는 작업도 어렵다. 그리고 특정 값을 공유해가면서 작업을 처리하기에 까다롭다.

    그래서 나온 해결법이 async/await이다.

    6. async/await

    async/await는 자바스크립트의 비동기 처리 패턴 중 가장 최근에 나온 문법이다.

    기존의 비동기 처리 방식인 콜백 함수와 프로미스의 단점을 보완한다.

    6-1. async/await 기본 문법

    // ES5
    async function 함수명() {
     await 비동기 처리 메서드명();
    }
    
    // ES6
    const 함수명 = async() => {
     await 비동기 처리 메서드명();
    }

    ◎ 먼저 함수 앞에 async 키워드를 붙인다. 그리고 함수의 내부 로직 중 HTTP 통신을 하는 비동기 처리 코드 앞에 await를 붙인다.

    ※ 주의할 점은 비동기 처리 메서드가 꼭 프로미스 객체를 반환해야 한다!

    6-2. async/await 예제

    ◎ async/await의 간단한 코드를 작성해보자.

     

    async/await

     

    fetchItems( ) 함수는 프로미스 객체를 반환하는 함수이다. fetchItems( ) 함수를 실행하면 프로미스가 resolve 되며 결과 값은 items 배열이 된다.

    Asynchronous( ) 함수를 실행하면 fetchItems( ) 함수의 결과 값인 items 배열이 resultItems 변수에 담겨 배열이 잘 출력된다.

    await를 사용하지 않으면 데이터를 받아온 시점에 콘솔을 출력할 수 있게 콜백 함수나 .then( )을 사용해야 한다.

    6-3. async/await 실용 예제

    ◎ async/await 문법은 여러 개의 비동기 처리 코드를 다룰 때 적절하게 사용할 수 있다.

    사용자와 할 일 목록을 받아오는 HTTP 통신 코드가 있다고 해보자.

     

    async/await 통신 code

    위 함수들을 실행하면 사용자 정보와 할 일 정보가 담긴 프로미스 객체가 반환된다.

    사용자 아이디가 1인 유저의 할 일 정보의 제목을 콘솔에 출력하는 코드이다.

    6-4. async/await 예외 처리

    ◎ async/await 에서 예외 처리는 try catch이다. 프로미스에서 에러 처리를 위해 .catch( )를 사용했던 것처럼 async에서는 catch { }를 사용하면 된다.

    위의 코드에 try catch 문법을 적용한 코드이다.

     

    try catch

    네트워크 통신 오류 또는 일반적인 오류까지도 catch로 잡을 수 있다.

    7. 느낀 점

    ◎ 서버와 통신하기 위해 비동기 처리는 필수적으로 알아야 한다.

    react에서는 fetch( ).then()을 통해 통신해 봤지만 또 다른 비동기 처리를 배워서 의미 있는 시간이었다.

    개인적으로는 async/await가 깔끔하고 보기 좋아서 앞으로 많이 사용할 문법이다.

    앞으로 서버와 통신할 때 무조건 사용해봐야겠다.

    개인적인 생각이지만, 콜백 함수는 되도록이면 사용을 자제해야겠다.. 콜백 지옥 싫어요~

    ※ 참조

    - 벨로퍼트님의 리액트 강의 시청한 내용 정리 (강의 내용을 정리하느라 틀린 부분이 있으면 피드백 부탁드립니다!!)

     

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

     

    Promise

    The Promise object represents the eventual completion (or failure) of an asynchronous operation, and its resulting value.

    developer.mozilla.org

    https://joshua1988.github.io/web-development/javascript/js-async-await/

     

    자바스크립트 async와 await

    (중급) 자바스크립트 개발자를 위한 async, await 사용법 설명. 쉽게 알아보는 자바스크립트 async await 개념, 사용법, 예제 코드, 예외 처리 방법

    joshua1988.github.io

     

Designed by Tistory.