Async

MINIMI·2023년 4월 20일
0

REACT

목록 보기
17/20
post-thumbnail

17-1. Intro

  • 동기작업과 비동기작업
    • 동기작업
      • 하나의 작업을 실행하고 마친 뒤에 다음 작업을 순차적으로 진행
    • 비동기 작업
      • 메인 흐름은 멈추지 않는 상태에서 특정 작업들을 백그라운드에서 처리하여 동시에 처리하는 것처럼 실행
      • 비동기 작업을 할 때 가장 많이 사용하는 방식이 콜백 함수를 이용하는 방식
      • 비동기 처리를 하기 위한 가장 흔한 방법은 콜백 함수를 이용하는 것
      • 특정 비동기 처리 이후 수행해야 할 내용을 또 정의해야 하는 경우에는 콜백 함수의 중첩이 생기고, 이러한 것들이 많이 추가 되면 콜백 지옥이 생길 수 있음
  • 잘못 된 예시
function increase(number, callback){
            setTimeout(() => {
               const result = number + 10;
               
               if(callback){
                callback(result);
               }
            }, 1000);
        }

        /* 여러번 순차적으로 1초마다 10씩 증가하게 하고 싶다면 중첩을 이용해서 호출할 수 있다. */
        console.log('start');
        increase(0, result => {
            console.log(result);
            increase(result, result => {
                console.log(result);
                increase(result, result => {
                    console.log(result);
                    increase(result, result => {
                        console.log(result);
                        increase(result, result => {
                            console.log(result);
                        })
                    })
                })
            })
        })

17-2. Promise

React 자체적으로는 Promise를 제공하지 않습니다. 하지만 React 애플리케이션에서 비동기 처리를 위해 Promise를 사용하는 것은 일반적입니다.

Promise는 자바스크립트에서 비동기 처리를 위한 객체입니다. 비동기 작업을 수행하고 그 결과를 나중에 처리하기 위해 Promise를 사용합니다. Promise 객체는 총 3가지 상태를 가지며, 이는 다음과 같습니다.

대기 중(pending): Promise 객체가 생성된 상태이며, 아직 결과가 처리되지 않은 상태
이행됨(fulfilled): Promise 객체가 성공적으로 처리된 상태이며, 결과 값이 존재함
거부됨(rejected): Promise 객체가 실패한 상태이며, 오류가 발생함
React에서 Promise를 사용하는 대표적인 예는 fetch() 메서드를 통한 API 호출입니다. fetch() 메서드는 Promise를 반환하며, 이를 이용하여 비동기적으로 데이터를 가져올 수 있습니다. 예를 들어, 다음과 같이 fetch() 메서드를 이용하여 데이터를 가져올 수 있습니다.

Copy code
fetch('https://api.example.com/data')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error(error))

위 예제에서 fetch() 메서드는 https://api.example.com/data URL에 GET 요청을 보내고, 이에 대한 응답을 Promise로 반환합니다. then() 메서드를 이용하여 응답 데이터를 JSON 형식으로 파싱하고, 다시 then() 메서드를 이용하여 파싱된 데이터를 출력합니다. 만약 에러가 발생하면 catch() 메서드를 이용하여 에러를 처리합니다.

React 애플리케이션에서 Promise를 사용하는 방법은 일반적으로 위와 같이 then() 메서드를 이용하여 비동기 작업을 처리하고, catch() 메서드를 이용하여 에러를 처리하는 것입니다.

  • 개선된 코드
/* Promise는 콜백 지옥같은 코드가 형성 되지 않게 하는 방안으로 ES6에서 도입 되었다. */

        function increase(number){
            /* resolve는 성공, reject는 실패를 의미 */
            const promise = new Promise((resolve, reject) => {
                setTimeout(() => {
                    const result = number + 10;

                    if(result > 50){ 
                        const e = new Error('NumberTooBig');
                        /* 실패시 결과값을 reject로 전달 */
                        return reject(e);
                    }

                    /* 성공 시 결과 값을 resolve의 인자로 전달 */
                    resolve(result);

                }, 1000);
            });

            return promise;
        }

        /* promise에서 resolve 함수로 전달한 값은 then 메소드에 전달하는 콜백함수의 매개변수를 이용해서 받아올 수 있다. 
        비동기 작업을 연달아서 수행한다고 해서 콜백 지옥이 생기는 것이 아니라 
        promise 객체를 반환 받아 then 메소드를 통해 그 다음 작업을 설정하기 때문에 코드 가독성이 개선된다. */
        increase(0).then(number => {
            console.log(number);

            return increase(number)    //처리 후 다시 promise를 리턴한다.
        })
        .then(number => {
            console.log(number);
            return increase(number);
        })
        .then(number => {console.log(number); return increase(number)})
        .then(number => {console.log(number); return increase(number)})
        .then(number => {console.log(number); return increase(number)})
        .then(number => {console.log(number); return increase(number)});

17-3. async / await

async/await는 비동기 처리를 위한 JavaScript의 문법 중 하나로, Promise를 더 쉽게 사용할 수 있도록 해줍니다.

기존의 Promise를 사용하는 방법에서는 then()과 catch()를 사용하여 비동기 처리 결과를 처리했습니다. 하지만 async/await을 사용하면 비동기 처리 결과를 try-catch 구문으로 처리할 수 있습니다.

예를 들어, Promise를 사용한 코드는 다음과 같습니다.

function fetchData() {
  return fetch('https://example.com/data')
    .then(response => {
      if (!response.ok) {
        throw new Error('Failed to fetch data');
      }
      return response.json();
    })
    .then(data => {
      console.log(data);
    })
    .catch(error => {
      console.error(error);
    });
}

이를 async/await로 바꾸면 다음과 같습니다.

async function fetchData() {
  try {
    const response = await fetch('https://example.com/data');
    if (!response.ok) {
      throw new Error('Failed to fetch data');
    }
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error(error);
  }
}

async/await을 사용하면 비동기 처리 결과를 보다 직관적으로 처리할 수 있습니다. await 키워드를 사용하여 비동기 처리 함수가 완료될 때까지 기다리면서 코드를 동기적으로 처리할 수 있습니다. try-catch 구문을 사용하여 예외 처리도 보다 쉽게 할 수 있습니다.

/* promise를 더 쉽게 사용할 수 있도록 async/await가 ES2017(ES8)에서 추가 되었다. */
        function increase(number){
            /* resolve는 성공, reject는 실패를 의미 */
            const promise = new Promise((resolve, reject) => {
                setTimeout(() => {
                    const result = number + 10;

                    if(result > 50){ 
                        const e = new Error('NumberTooBig');
                        /* 실패시 결과값을 reject로 전달 */
                        return reject(e);
                    }

                    /* 성공 시 결과 값을 resolve의 인자로 전달 */
                    resolve(result);

                }, 1000);
            });

            return promise;
        }

        /* 함수의 선언부에 sync 키워드를 이용하고, 함수 내부에서 promise를 사용할 때 await 키워드를 이용한다.
        await가 붙은 promis 호출 구문은 promise 작업에 끝날 떄 까지 기다리며 실행하게 된다, */
        async function run(){
            try{
                let result = await increase(0);
                console.log(result);

                result = await increase(result);
                console.log(result);

                result = await increase(result);
                console.log(result);

                result = await increase(result);
                console.log(result);

                result = await increase(result);
                console.log(result);

                result = await increase(result);
                console.log(result);
            }catch(e){
                console.log(e);
            }
        }

        run();
profile
DREAM STARTER

0개의 댓글