ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Promise & async / await
    ⏰ 오늘의 공부/기타 2020. 1. 27. 01:32

     

    node.js 와 react 를 다루면서 비동기 처리를 제대로 하지 못해 드럽게 코드를 짜고 있는 나를 보면서 꼭 정리를 하겠다 생각했었는데

    마침 설연휴를 맞아 제대로 공부하면서 자바스크립트 비동기 처리 !!!! 마스터 하고자 한다. 

     

     

    Promise ? 

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

     

    그렇다면 비동기 처리란 ?

    ‘특정 코드의 실행이 완료될 때까지 기다리지 않고 다음 코드를 먼저 수행하는 자바스크립트의 특성’

    → 자칫하다가 Callback hell 에 빠질 수 있다.. like 마치 내 예전 코드들처럼 ㅎ

     

    promise 의 3가지 상태

    • pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태
    • fulfilled(이행) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태
    • rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태

     

    pending - new Promise() 메소드 호출하면 pending 상태가 된다.

    new Promise(function (resolve, reject) {
      // ...
    });

     

    Fulfilled - 콜백 함수의 인자 resolve 를 아래와 같이 실행하면 Fulfilled 가 된다.

    new Promise(function (resolve, reject) {
      resolve();
    });
    function getData() {
      return new Promise(function (resolve, reject) {
        var data = 100;
        resolve(data);
      });
    }
    
    // resolve()의 결과 값 data를 resolvedData로 받음
    getData().then(function (resolvedData) {
      console.log(resolvedData); // 100
    });

    이행 상태에서 then()을 활용하여 처리 결과 값 받는다. 

     

    Rejected - reject 인자로 reject() 메소드를 실행하면 rejected 상태

    new Promise(function (resolve, reject) {
      reject();
    });
    function getData() {
      return new Promise(function (resolve, reject) {
        reject(new Error("Request is failed"));
      });
    }
    
    // reject()의 결과 값 Error를 err에 받음
    getData().then().catch(function (err) {
      console.log(err); // Error: Request is failed
    });

    실패 상태가 되면 실패 처리의 결과 값을 catch()로 받을 수 있다.

     

     

    여러 개의 프로미스 연결하기 

    function getData() {
      return new Promise({
        // ...
      });
    }
    
    // then() 으로 여러 개의 프로미스를 연결한 형식
    getData()
      .then(function (data) {
        // ...
      })
      .then(function () {
        // ...
      })
      .then(function () {
        // ...
      });

    Promise에서 에러 처리하기 - catch()

    // catch()로 오류를 감지하는 코드
    function getData() {
      return new Promise(function (resolve, reject) {
        resolve('hi');
      });
    }
    
    getData().then(function (result) {
      console.log(result); // hi
      throw new Error("Error in then()");
    }).catch(function (err) {
      console.log('then error : ', err); // then error :  Error: Error in then()
    });

     

     

    async / await 

    • async와 await는 자바스크립트의 비동기 처리 패턴 중 가장 최근에 나온 문법
    • 기존의 비동기 처리 방식인 콜백 함수와 프로미스의 단점을 보완하고 개발자가 읽기 좋은 코드를 작성할 수 있게 도와준다.

     

    기본 문법

    async function 함수명() {
      await 비동기_처리_메소드_명();
    }
    • 먼저 함수의 앞에 async 라는 예약어를 붙인다.
    • 그러고 나서 함수의 내부 로직 중 HTTP 통신을 하는 비동기 처리 코드 앞에 await를 붙인다.
    • (주의해야 할 점 : 비동기 처리 메서드가 꼭 프로미스 객체를 반환해야 await가 의도한 대로 동작한다 ! )

     

    실용 예제

    async / await 문법이 가장 빛을 발하는 순간 : 여러개의 비동기 처리 다룰 때

    await 사용하기 위해서는 먼저 Promise 함수 정의하여야 한다 !

    function fetchUser() {
      var url = 'https://jsonplaceholder.typicode.com/users/1'
      return fetch(url).then(function(response) {
        return response.json();
      });
    }
    
    function fetchTodo() {
      var url = 'https://jsonplaceholder.typicode.com/todos/1';
      return fetch(url).then(function(response) {
        return response.json();
      });
    }
    
    async function logTodoTitle() {
      var user = await fetchUser();
      if (user.id === 1) {
        var todo = await fetchTodo();
        console.log(todo.title); // delectus aut autem
      }
    }
    1. fetchUser()를 이용하여 사용자 정보 호출
    2. 받아온 사용자 아이디가 1이면 할 일 정보 호출
    3. 받아온 할 일 정보의 제목을 콘솔에 출력

    await 문법은 Async 함수 안에서만 사용이 가능하고, async 내에서라고 해도 함수 안에 선언된 경우 사용이 불가하다.

    → 아래와 같이 fn 이라는 함수 안에서 await 문법은 문법적 오류가 발생

    async function asyncMain () {
        let fn = ()=> {
            let data = await asyncFunction1('hello');
            return data;
        };
    
        let result = fn();
        console.log(result);
    }
    
    asyncMain();

     

    에러 처리 - try catch 활용

    async function logTodoTitle() {
      try {
        var user = await fetchUser();
        if (user.id === 1) {
          var todo = await fetchTodo();
          console.log(todo.title); // delectus aut autem
        }
      } catch (error) {
        console.log(error);
      }
    }

    catch 를 통해 발생한 네트워크 오류 뿐 아니라 간단한 타입 오류까지 잡아낼 수 있다.

    발견한 error 는 error 객체에 담기기 때문에 유형에 맞게 에러 처리 가능하다.

     

     


    이걸 바탕으로 코드 리팩토링을 진행했다...속이 다 시원하다. 후

     

    참고 : https://joshua1988.github.io/web-development/javascript/promise-for-beginners/

     

    '⏰ 오늘의 공부 > 기타' 카테고리의 다른 글

    Spark  (0) 2020.03.02
    Spark - RDD  (0) 2020.02.01
    Redis  (0) 2020.01.24
    Proxy 설정  (0) 2020.01.24
    AJAX  (0) 2020.01.24

    댓글

Designed by Tistory.