본문 바로가기

자바스크립트

[javascript] async ~ await 에 대한 정리

반응형

 

async ~ await  란?

async 함수는 항상 Promise를 반환하고, await 키워드는 비동기 작업이 완료될 때까지 기다린다.  특히 AJAX 호출, 파일 읽기/쓰기, 타이머 함수 등과 같이 비동기적으로 처리해야 하는 작업이 있는 경우 유용하게 활용할 수 있다.

 

다르게 말하면, async 는 비동기를 의미하며, await 은 비동기 처리에 대한 Promise 를 반환받기 전 까지 다음 코드 실행을 대기토록 하는 키워드 이다. 이는 내부적으로 Promise 를 추상화하였기 때문에  promise.then 으로 일일이 접근할 필요 없이 준비된 데이터를 즉시 반환받을 수 있다.

promise 는 비동기적 데이터를 가져올 때, 이 데이터를 정상적으로 사용하려면 .then() 메소드에 접근 후 콜백함수의 매개변수로 전달받은 변수에 패칭된 결과를 받아와서 출력 후 사용해야 한다.

new Promise( ( r, e ) => {

    return r ( ' 데이터 가져온다 ' )

} ).then( ( result) => console.log(result) // 출력--> 데이터 가져온다 )

 

 

활용 예시

Promise 와 async ~ await 을 활용한 예시

보통 I/O 요청을 통한 데이터 fetching , 데이터베이스 입출력 등에 활용되는데, 아래 예시는 Promise 를 사용하여 데이터 패칭 로직을 흉내낸 코드 이다.  fetchData 는 Promise 를 반환하기 때문에 원래 라면 .then 으로 접근하여 Pending 상태인 데이터를 직접 처리해줘야 한다.

// 비동기적으로 데이터를 가져오는 함수
function fetchData() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve("Data fetched!");
    }, 2000);
  });
}

 

그러나, async ~ await 를 활용하면 .then 으로 접근할 필요 없이 데이터가 보류에서 이행이 될 준비가 완료된다면 즉시 반환되므로 result 변수에 담긴 데이터를 바로 활용할 수 있게 된다. fetchDataAsync 함수를 호출해보면  await 이 붙은 함수가 호출되어 종료될 때 까지 다음 줄의 코드를 실행하지 않고 대기한다. 즉, 비동기적 로직을 동기적 로직인 것처럼 처리된다.

 

// 비동기 함수를 호출하고 결과를 출력
async function fetchDataAsync() { 
  console.log("Start");// 1번째 출력) Start

  // fetchData 함수를 비동기적으로 호출하고 완료될 때까지 기다림
  const result = await fetchData();

  // fetchData 함수가 처리될 때 까지 대기 후 완료되면 데이터를 출력한다.
  console.log(result); // 2번째 출력) Data fetched!

  console.log("End"); // 3번째 출력) End
}

// fetchDataAsync 함수 호출
fetchDataAsync();

 

 

여러 비동기 작업을 병렬로 처리하기

만일 비동기적 작업을 병렬로 처리해야 하는 경우에는 Promise.all 을 사용할 수 있다. Promise.all 은 인자로 전달받은 배열의 각 요소에 들어가는 비동기적 처리 로직을 병렬적으로 처리하여 데이터를 반환받을 수 있게 한다. 그리고 all 또한 async ~ await 을 사용하여 처리를 단순화할 수 있는데, 아래 예시와 같이 await 키워드를 붙이면 Promise.all 을 통해 반환된 데이터를 즉시 반환받아 사용할 수 있다.

// 여러 비동기 작업을 병렬로 처리하는 함수
async function parallelAsyncTasks() {
  console.log("Start"); // 출력 1

  // Promise.all을 사용하여 여러 비동기 작업을 병렬로 실행
  const [a, b] = await Promise.all([
    new Promise(resolve => setTimeout(() => resolve("Task 1 done!"), 2000)),
    new Promise(resolve => setTimeout(() => resolve("Task 2 done!"), 1000))
  ]);
  
  console.log(a, b) // 출력 2 ) Task 1 done! Task 2 done!

  console.log("All tasks completed"); // 출력 3
  console.log("End"); // 출력 4
}

// parallelAsyncTasks 함수 호출
parallelAsyncTasks();

 

 

만일 async ~ await 을 사용하지 않고 Promise.all 을 사용한다면 아래와 같이 .then 메소드로 접근하여야 한다.

// 여러 비동기 작업을 병렬로 처리하는 함수
async function parallelAsyncTasks() {
  console.log("Start");

  // Promise.all을 사용하여 여러 비동기 작업을 병렬로 실행
 Promise.all([
    new Promise(resolve => setTimeout(() => resolve("Task 1 done!"), 2000)),
    new Promise(resolve => setTimeout(() => resolve("Task 2 done!"), 1000))
  ]).then((result)=>{
   console.log(result)
  })

  console.log("All tasks completed");
  console.log("End");
}

// parallelAsyncTasks 함수 호출
parallelAsyncTasks();
반응형