[javascript] 비동기/Promise/async & await 이해하기

gongyoon·2022년 6월 9일
0

JS

목록 보기
3/5

1. 비동기란?

앞서 동기란 순차적으로 작업을 수행해 나가는것을 말함. ex) A 작업 종료 > B 작업 수행
비동기는 진행중인 작업이 있음에도 다른 작업을 수행해 나가는것을 말함.

2. 비동기 통신 방법

오래전에 jquery ajax로 비동기 통신을 사용하면서 유기적인 흐름제어가 안된다는 점과 callback hell에 대한 단점을 느꼈던 때가 있었는데 최신 자바스크립트 문법에 지원되는 Promise 와 async & await를 제대로 이해하기 위해 정리를 해보았다.

2-1. Promise

Promise는 비동기 작업의 단위이며 통신의 상태와 처리결과를 관리해주는 객체이다.

const promise1 = new Promise((resolve, reject) => {
 	resolve('성공'); /* or reject('실패') */

});

promise1
.then((value) => console.log(value)) // 성공
.catch((error) => console.log(error)); 

위와 같이 Promise 객체를 생성과 할당을 하게 되면 비동기 작업이 바로 실행된다. Promise의 생성자를 보면
executor라는 인자를 함수 형태로 전달하는데 그 함수 내의 인자로 resolve, reject가 존재한다. 각각 작업이 성공, 실패
했을떄 호출하는 함수로 각각 후속처리 함수 then, catch로 결과값을 인자로 넘겨주며 Promise Chain을 유기적으로 형성해준다.
이 부분을 흐름제어라고 한다.

하지만 이것 또한 Chain이 길어지게 되면 직관성이 떨어져 보인다.

2-2. Async & Await

async 키워드를 사용해 비동기 함수를 쉽게 만들 수 있다. 기존에 작성한 executor 함수로부터 몇가지 규칙을 적용한
다면 new Promise(...)를 리턴하는 함수를 async 함수로 변환할 수 있다.
(new Promise(...)와 async 함수 모두 리턴값은 Promise이다.)

  • 함수에 async 키위드를 붙인다.
  • new Promise... 부분을 없애고 executor 본문 내용만 남긴다.
  • resolve(value); 부분을 return value; 로 변경한다.
  • reject(new Error(…)); 부분을 throw new Error(…); 로 수정한다.
function setTimeoutPromise(ms) {
  return new Promise((resolve, reject) => {
    setTimeout(() => resolve(), ms);
  });
}

async function startAsync(age) {
  if (age > 20) return `${age} success`;
  else throw new Error(`${age} is not over 20`);
}

async function startAsyncJobs() {
  await setTimeoutPromise(1000);
  const promise1 = startAsync(25);
  try {
    const value = await promise1;
    console.log(value);
  } catch (e) {
    console.error(e);
  }
  const promise2 = startAsync(15);
  try {
    const value = await promise2;
    console.log(value);
  } catch (e) {
    console.error(e);
  }
}

startAsyncJobs();

await는 Promise가 fullfilled나 rejected가 될때까지 기다리는 키워드이다. async 함수내에서만 사용 가능하고 async
함수의 리턴값은 Promise이므로 흐름 제어를 해야 한다. Promise의 흐름 제어는 then(), catch()를 통해서 했다면 async 함수는
try, catch 문을 사용하면 된다. 위 코드의 startAsyncJobs 함수의 setTimeoutPromise가 상태가 변경될때까지 대기해야한다.

마치며

Promise 와 Async & Await 모두 비동기 작업이고 흐름제어를 통해 내부 작업을 동기적으로 제어하는 기능을 제공해주었다.
다양한 라이브러리와의 호환성과 효율적인 코드를 만들어내기 위해 더 공부해봐야겠다.

참고

https://elvanov.com/2597

profile
공부하며 성장하는 사람이 되고 싶은 개발자.

0개의 댓글