[ TIL ] 프로그래머스 DAY 12 : Module 그리고 대망의 비동기 Promise & async, await

🙋🏻‍♂️

지금 정리하는 내용은 일부 오타잘못된 내용이 기입되어 있을 수 있습니다. 가급적 오류를 줄이겠지만 일부분 발생할 수 있다는 점 양해부탁드립니다. 잘못된 내용 수정이나 추가 설명이 필요할 때 댓글로 알려주시면 감사하겠습니다.

🍪 배운 목록

  • Module
  • 비동기처리
  • Promise
  • async, await

🍽 배운 내용 요약 및 중요한 것

Module

js에서 모듈은 import로 쉽게 불러 사용할 수 있다.

먼저 하나의 js에서 몰아서 사용하기 위해 html에 script로 불러올 때 type을 module로 지정해야 한다.

html

<body>
<script src="./index.js" type="module"></script>
</body>

testModule.js

export const test = ()=>{
	.....
};

defaultModule.js

const defaultModule = ()=>{
	.....
};

export default defaultModule;

위처럼 export한 js들을 하단처럼 import하여 사용할 수 있다.

index.js

import {test} from "./testModule.js";
import default from "./defaultModule.js";

test();
defaultModule();

비동기처리

자바스크립트는 싱글스레드로 비동기처리를 위해 이벤트루프를 사용한다는 것은 이전 TIL에 정리한 적이 있습니다.

자바스크립트에서 비동기를 헨들링할 수 있는 방법이 총 3가지가 있는데

  1. callBack function
  2. Promise 객체
  3. async, await 키워드

위 3가지는 하단에 자세히 설명을 하겠습니다.

비동기처리를 하는 이유는 순차적으로 실행되는 코드에서 어떤 UI 관련 렌더링 작업이 오래걸리는 함수를 만나게 되면 브라우저가 잠시 멈추게되어 사용자 경험이 매우 저하됩니다. 따라서 이러한 함수는 비동기적으로 실행되게하여 다른 코드들이 실행되다가 먼저 동기적으로 처리되는 코드가 끝나면 실행되어 사용자가 크게 불편함없이 웹서비스를 이용할 수 있게 됩니다.

따라서 프론트엔드 개발자는 이러한 비동기적 코드진행을 이해하고 사용할 수 있어야 합니다.

Promise

프로미스객체는 es6이후 나온 비동기를 처리하기 위한 객체로

const myFirstPromise = new Promise((resolve, reject) => {
  // do something asynchronous which eventually calls either:
  //
  //   resolve(someValue)        // fulfilled
  // or
  //   reject("failure reason")  // rejected
});

resolve 및 reject 인수를 전달할 실행 함수. 실행 함수는 프로미스 구현에 의해 resolve와 reject 함수를 받아 즉시 실행됩니다(실행 함수는 Promise 생성자가 생성한 객체를 반환하기도 전에 호출됩니다). resolve 및 reject 함수는 호출할 때 각각 프로미스를 이행하거나 거부합니다. 실행 함수는 보통 어떤 비동기 작업을 시작한 후 모든 작업을 끝내면 resolve를 호출해 프로미스를 이행하고, 오류가 발생한 경우 reject를 호출해 거부합니다. 실행 함수에서 오류를 던지면 프로미스는 거부됩니다. 실행 함수의 반환값은 무시됩니다.

위와 같이 사용할 수 있습니다. Promise의 상태는 pending, fullfilled, rejected 3가지로 나눠지고 pending은 resolve, reject가 되지 않은 결과를 기다리는 Promise 상태이고 fullfilled는 resolve가 실행된 상태를 뜻하며 rejected는 reject가 실행된 상태를 뜻합니다.

Promise 상태가 fullfilled라면 Promise.then()으로 Promise 객체 내부에 접근하여 헨들링이 가능해집니다. 반대로 rejected라면 Promise.catch()를 사용해 처리가 가능합니다.

각각 then, catch는 내부에서 ()=>{} 콜백함수로 인자에 result, error를 받아 Promise에서 던져준 데이터를 받아 헨들링하게 됩니다.
위 메소드에서 return 무언가를 하게 되면 Promise객체를 반환하므로 다시 .then, .catch로 체이닝이 가능합니다.

async, await

가장 트렌디하게 비동기를 처리할 수 있는 최신문법으로 Promise.then().catch()를 대체할 수 있습니다. 또한, 비동기적으로 실행되는 함수를 동기적으로 실행되게끔 처리할 수 있어 많이 사용하게 되는 패턴입니다.

Promise 코드

Promise.then((res)=>{
	console.log(res)
}).catch((err)=>{
	console.log(err)
})

async, await 코드

const asyncFunc = async ()=>{
	try{
		const res = await 비동기처리함수
        console.log(res)
	} catch(err){
		console.log(err)
	}
}

위 코드를 보면 then, catch가 try, catch로 바뀐 것을 볼 수 있다.
사실 async, await에 try, catch를 사용하지 않아도 되지만 정확한 오류 헨들링을 위해 사용하게 됩니다. 그리고 async로 함수를 감싸주어 선언하게 되면 반환값은 전부 Promise로 감싸지게되어 Promise 객체가 됩니다.

따라서 async, await를 사용하게 되면 then, catch, Promise를 굳이 명시하지 않아도 되는 것입니다.

🧘🏻‍♂️ 어려웠던 점 및 후기

콜백함수에 대한 설명을 제외하긴 했지만 콜백함수는 비동기를 처리하기 위해서는 콜백함수 내에서 다시 콜백함수를 인자로 넣어주고 넣어주고를 반복해서 들여쓰기의 depth가 깊어집니다. 그래서 비동기를 처리하기 위해서 많은 코드를 안에 들여써야 하기때문에 스파게티코드가 될 수 있을 가능성이 높습니다. 따라서 Promise 객체를 사용해 .then, .catch를 사용하여 코드를 가독성있게 만드는게 필요합니다.

그리고 하나 배운거는 async await를 사용하게 되면 내부적으로도 동기적 실행이 될 줄 알았는데 실제로는 비동기적으로 코드를 실행하면서 await 키워드가 걸린 함수 실행에 대해서만 Promise의 상태가 pending을 벗어날때까지 기다리는 것을 알게 되었습니다.

🔗 참조

프로그래머스

좋은 웹페이지 즐겨찾기