[TIL] 프론트엔드 Day 12

📚 공부한 내용

1. 모듈

10일차에 컴포넌트 방식의 설계를 하면서 실습했던 Simple Todo List는 여러 컴포넌트를 html 안의 <script src="">를 이용해서 외부 JS파일을 로딩했는데, 이 때 강조했던 부분이 파일간의 의존성이다. 만약 App.js파일에서 TodoList.js와 TodoForm.js 파일의 함수를 사용한다면 반드시 App.js파일의 스크립트를 읽어오기 전에 TodoList.js와 TodoForm.js를 읽어와야 한다. 이를 고려하지 않고 html을 작성하면 아래와 같은 오류를 직면하게 된다.

하지만 파일이 많아질 수록 파일간의 스크립트 의존성 파악이 더욱 힘들어지며, 이를 더 간편하게 관리할 수 있도록 해주는 것이 모듈이다.

사용법

다른 파일에서 export를 통해 내보내진 변수, 함수 등을 import 명령어를 이용해서 불러온다. 변수나 함수는 하나 또는 그 이상일 수 있으며, 사용 방식에 따라서 어떤 스크립트를 불러올지 정할 수 있다.
아래는 그 예시이다.

// 파일 안의 모든 정보를 불러올 때
import * from "./src/storage.js"

// 파일 안에 export default로 설정된 함수 또는 변수를 불러올 때
import TodoList from "./src/TodoList.js"

// 파일의 일부를 불러올 때
import { getItem } from "./src/storage.js"

// 파일의 일부를 다른 이름으로 사용할 때
import { getItem as g } from "./src/storage.js"

// export default로 설정된 것과 추가로 다른 일부분을 불러올 때
import TodoList, { util } from "./src/TodoList.js"

2. 비동기 처리

2-1. 비동기 처리란

어떤 코드를 즉시 처리할 수 없을 때, 처리가 끝날 때까지 기다리지 않고 그 동안 다음 코드를 우선 수행하는 처리방식. addEventListener, setTimeout 등이 대표적이다.

2-2. callback 방식

callback 방식은 비동기 처리한 결과물을 callback 함수에 넘겨서 다음 동작을 진행하는 비동기 처리방식이다. 예를 들어 비동기로 id를 입력받아 name을 가져오고 그 text를 console에 출력해야 한다고 가정하면 아래와 같을 것이다.

	// id를 입력받아 비동기로 name을 가져오는 함수
	getNameById(id, (name) => {
      console.log(name);
    });

callback 방식은 callback hell이라는 용어가 존재할 만큼 비동기 처리한 데이터를 계속해서 비동기로 처리할 때 가독성이 좋지않다. 예를 들어 id로 name을 찾고 name으로 주소를 찾고, 주소를 이용해서 우편번호를 찾는다고 한다면?

	getNameById(id, (name) => {
      getAddressByName(name, (address) => {
      	getCodeByAddress(address, (code) => {
        	console.log(code);
        });
      });
    });

이렇게 처리과정이 늘어날수록 코드의 구조를 이해하는 것이 어려워진다.

2-3. Promise

Promise는 비동기 처리를 체인 형식으로 제어할 수 있게하는 객체다. Promise에는 비동기 처리 상태를 나타내는 PromiseStatus와 처리 결과인 PromiseResult로 구성된다. Status는 비동기 처리가 정상적으로 끝난 fulfilled, 비동기 처리가 끝나지 않고 진행중인 pending, 비정상으로 종료된 rejected 세 가지 중 하나다.

Promise 객체에 then 명령어를 이용해서 다음 동작을 지정하는 것이 가능하다. then 위의 callback에서의 코드를 Promise 객체를 이용해서 작성하면 아래와 같다.

// 모든 get 함수가 Promise 객체를 return한다고 가정할 때.
	const code = new Promise((resolve, reject) => resolve(getNameById(id)))
        .then((result) => {
          return getAddressByName(result)
        }).then((result) => {
          return getCodeByAddress(result)
        }).then((result) => {
          console.log(result)
        });
    

Promise의 내장함수

  • catch
    try-catch 구문과 비슷한 역할. rejected 상태의 Promise가 반환되는 경우 catch에 있는 코드가 실행된다.

  • finally
    Promise의 상태에 상관없이 모든 비동기 처리가 끝난 이후에 finally에 있는 코드가 실행된다.

  • Promise.all
    입력받은 모든 Promise를 순차적으로 실행한다.

  • Promise.race
    입력받은 모든 Promise를 동시에 실행한다. 이들 중 가장 먼저 종료된 결과를 반환한다. (reject, resolve 상관 없이)

  • Promise.any
    입력받은 모든 Promise를 동시에 실행한다. 이들 중 가장 먼저 resolve한 Promise 결과를 반환한다.

  • Promise.allSettled
    입력받은 모든 Promise의 실행 결과를 배열에 담아서 반환한다.

  • Promise.resolve
    status가 fulfilled, result가 입력받은 값인 Promise를 반환한다.

  • Promise.reject
    status가 rejected, result가 입력받은 값인 Promise를 반환한다.

2-4. async, await

async와 await은 Promise를 이용하는 또 다른 비동기 처리방식이다.

  • async 명령어를 함수의 이름 앞에 붙이면 기존에 반환하던 값을 Promise에 감싸서 return한다.

  • await 명령어는 async function 내부에서만 사용가능한 명령어다. await은 Promise가 전부 처리될 때까지 기다리기 때문에 일반적인 동기 코드와 동일하게 위에서 아래로 순서대로 실행된다.

  • 만약 Promise가 reject된다면 try-catch를 이용해서 오류를 처리할 수 있다.

아래는 지금까지 예시로 들었던 코드를 asyncawait을 사용해서 작성한 것이다.

  // 모든 get 함수가 Promise 객체를 return한다고 가정할 때.
  const getCodeById = async (id) => {
    const name = await getNameById(id);
    const address = await getAddressByName(name);
    const code = await getCodeByAddress(address);
    return code;
  };

이처럼 asyncawait을 이용하면 더욱 가독성이 좋은 비동기 처리코드를 작성하는 것이 가능하다.


📝 더 공부할 것

비동기 처리, 함수형 프로그래밍에서의 비동기 처리


🤔 느낀점

3주차로 넘어오면서 확실히 배우는 양과 공부할 내용이 더 많다. 비동기 처리는 익숙하지도 않고 중요하게 느껴져서 확실하게 정리해야겠다. 아직 함수형 프로그래밍 강의도 전부 듣고 정리하지 못했고, 새로나온 과제도 완성하지 못했다. 다음주는 악명높은 노션클로닝 기간이다. 이번주에 최대한 많이 해놓아야 한다.


Reference

프로그래머스 프론트엔드 데브코스

좋은 웹페이지 즐겨찾기