async, await

윤한영·2023년 9월 10일
0

React

목록 보기
6/10

🐣 혼자 공부하는 용도로 블로그를 보면서 작성한 거라 내용이 상당상당히 비슷합니다. 혹시나 보게 될 사람이 있으시다면 참고 바랍니다!


async : 비동기 작업을 만드는 손쉬운 방법

async 키워드는 함수를 선언할 때 붙여줄 수 있다.

async 함수는 Promise와 굉장히 밀접한 연관을 가지고 있는데, 기존에 작성하던 executor 로부터 몇 가지 규칙만 적용한다면 new Promise(...)를 리턴하는 함수를 async 함수로 손쉽게 변경할 수 있다.


  • 함수 function 키워드 앞에 async 키워드를 붙인다.

  • new Promise(...) 부분을 없애고 executor 본문 내용만 남긴다.

  • resolve(value); 부분을 return value; 로 변경한다.

  • reject(new Error(...)); 부분을 throw new Error(...); 로 수정한다.

/* 이전 형태는 이렇게
function startAsync(age) {
  return new Promise((resolve, reject) => {
    if(age > 20) resolve(`${age} sucess`);
    else reject(new Error(`${age} is not over 20`));
  });
}
*/

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

const promise03 = startAsync(25);
promise03
	.then((value) => {
  		console.log(value);
	})
	.catch((error) => {
  		console.error(error);
	});

const promise04 = startAsync(15);
promise04
	.then((value) => {
  		console.log(value);
	});
	.catch((error) => {
  		console.error(error);
	});

완전히 동일하게 동작한다. 세부적으로는 동작이 미묘하게 다를 수 있겠지만!!!
이 동작을 통해서 알 수 있는 것이 있다~

async 함수의 리턴 값은 무조건 Promise 이다!!!



await : Promise 가 끝날 때까지 기다리거라!!

await 는 왠지 wait 가 있으니까 기다리라는 뜻 같은데 그게 맞다! await 는 Promise 가 fulfilled 기 되든지 rejected 가 되던지 아무튼 간에 끝날 때까지 기다리는 함수이다.

  • await는 async 함수 내부에서만 사용할 수 있다
function setTimeoutPromise(delay) {
  return new Promise((resolve) => setTimeout(resolve, delay));
}
// delay : 1000이 인자로 넘어오고, Promise 생성(비동기 작업 실행)
// setTimeout(resolve, 1000);, 1초 후에 resolve 리턴

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

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

startAsyncJobs();

await 의 특성을 살펴보자!

  1. 문법적으로 await [[Promise 객체]] 이렇게 사용한다.

  2. await 는 Promise 가 완료될 때까지 기다린다. 그러므로 setTimeoutPromise 의 executor 에서 resolve 함수가 호출될 때까지 기다린다. 그 시간동안(1초) startAsyncJobs 의 진행은 멈춰있다.

  3. await 는 Promise 가 resolve 한 값을 반환한다. async 함수 내부에서는 리턴하는 값을 resolve 한 값으로 간주하므로, ${age} success 가 value 로 들어온다는 것을 알 수 있다.

  4. 해당 Promise 에서 reject 가 발생한다면 예외가 발생한다. 이 예외 처리를 하기 위해 try-catch 구문을 사용한다. reject 로 넘긴 에러(asycn 함수 내에서는 throw 한 에러)는 catch 절로 넘어간다.



왜 await 는 async 함수에서만 쓸 수 있을까?

비동기 작업으로부터 파생된 모든 작업은 비동기 작업으로 간주할 수 있다.

동기 환경에서 비동기 작업을 마냥 기다리는 건 의미가 없다. 비동기 작업의 의의는 뭘까? 항구에서 배를 떠나보낸 뒤, 그 동안 어제 잡아왔던 물고기를 포장하거나 새로운 거래처를 뚫는 등 다른 작업들을 수행할 수 있도록 하는 것이다. 고기 잡이 배를 떠나보내고 아무것도 하지 않고 기다리기만 한다면 비동기 작업의 의의가 없다!

반면, 비동기 환경에서 비동기 작업의 결과를 기다리겠다는 것은 다소 의미가 있다. 기다린다는 것은 동기 작업처럼 동작한다는 뜻이고, 이는 종종 유용하다. 예를 들어 생선들을 모두 손질해야 요리를 시작할 수 있을 것이고, 그물을 건져 올려야 다시 내릴 수 있을 것이다. 마냥 기다리는 게 정답일 때도 있다! 그 때 await 를 사용하는 것이다.

비동기는 동작 특성상 실제 작업과 그 작업의 후속조치를 따로 분리시킬 수 밖에 없는데, (그래서 then, catch 등을 사용했는데) async 와 await 를 사용하면 하나의 흐름 속에서 코딩을 할 수 있게 해준다.

실제 작업이 끝난 다음 그 후속조치를 수행하는 것이 아니라, 실제 작업이 끝나는 걸 기다린 다음 코드를 수행한다의 느낌!!!





참고자료

나중에 참고해보자~

0개의 댓글