WeniVooks

검색

JavaScript 에센셜

async, await

async/awiat를 사용하면 비동기 코드를 더 쉽게 작성할 수 있습니다. async 키워드는 어떤 함수든 프로미스 객체를 반환하게 만들 수 있습니다. await는 async 함수 안에서 사용되며, Promise가 처리될 때가지 함수의 실행을 일시 중지합니다. 처리가 완료되면 프로미스 객체의 fulfilled 값을 반환합니다.

다음 두 코드는 동일하게 동작합니다.

function test() {
  return Promise.resolve('Hello world');
}
function test() {
  return Promise.resolve('Hello world');
}
async function test() {
  return 'Hello world';
}
async function test() {
  return 'Hello world';
}

await는 async 함수 안에서 사용되며, Promise가 처리될 때가지 함수의 실행을 일시 중지합니다. 처리가 완료되면 프로미스 객체의 fulfilled 값을 반환합니다.

async function message() {
  const hello = await new Promise((resolve) => {
    setTimeout(() => {
      resolve('hello');
    }, 100);
  });
 
  const world = await new Promise((resolve) => {
    setTimeout(() => {
      resolve('world');
    }, 100);
  });
 
  console.log(`${hello} ${world}`);
}
 
message();
async function message() {
  const hello = await new Promise((resolve) => {
    setTimeout(() => {
      resolve('hello');
    }, 100);
  });
 
  const world = await new Promise((resolve) => {
    setTimeout(() => {
      resolve('world');
    }, 100);
  });
 
  console.log(`${hello} ${world}`);
}
 
message();

위의 코드를 통해 알 수 있는 await의 중요한 특징은 바로 async 함수 안에서 코드의 실행 순서를 확정 지을 수 있다는것 입니다. 비동기적 코드를 동기적 코드처럼 읽을 수 있어, async를 이용하면 기존의 Promise를 이용하는것 보다 더 가독성 있는 코드를 만들 수 있습니다.

위의 코드를 Promise 만 이용하도록 변경해보면 더 명확해집니다.

function message() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve('hello');
    }, 100);
  }).then((hello) => {
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve(`${hello} world`);
      }, 100);
    });
  });
}
function message() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve('hello');
    }, 100);
  }).then((hello) => {
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve(`${hello} world`);
      }, 100);
    });
  });
}

만약 async 함수 내에서 오류가 발생하면 어떻게 처리해야할까요? Promise에서 catch 메서드를 사용하여 오류를 처리했던 것처럼 async/await는 오류를 처리하기 위해 try/catch 문을 사용합니다. try 문 안에서 오류가 발생하면 catch 문으로 이동하여 오류를 처리합니다.

async function message() {
  try {
    const hello = await new Promise((resolve) => {
      setTimeout(() => {
        resolve('hello');
      }, 100);
    });
 
    const world = await new Promise((resolve) => {
      setTimeout(() => {
        resolve('world');
      }, 100);
    });
 
    console.log(`${hello} ${world}`);
  } catch (error) {
    console.error(error);
  }
}
async function message() {
  try {
    const hello = await new Promise((resolve) => {
      setTimeout(() => {
        resolve('hello');
      }, 100);
    });
 
    const world = await new Promise((resolve) => {
      setTimeout(() => {
        resolve('world');
      }, 100);
    });
 
    console.log(`${hello} ${world}`);
  } catch (error) {
    console.error(error);
  }
}

실습 fetch 통신으로 수정한 코드에 async와 await를 사용해보세요.

async function fetchSuperheroes() {
  try {
    const response = await fetch(
      'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json',
    );
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    const data = await response.json();
    console.log(data);
    return data;
  } catch (error) {
    console.error(error);
  }
}
fetchSuperheroes();
async function fetchSuperheroes() {
  try {
    const response = await fetch(
      'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json',
    );
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    const data = await response.json();
    console.log(data);
    return data;
  } catch (error) {
    console.error(error);
  }
}
fetchSuperheroes();
12.3 fetch API13장 정규표현식