await/async

.esc·2021년 2월 28일
0

await/async

await/async.then보다 더 가독성도 좋고 쓰기도 쉽게 promiseresult값을 얻을 수 있도록 해주는 문법이다.

async

asyncfunction 앞에 위치한다.
function 앞에 async를 붙이면 그 function은 항상 promise를 반환한다.
다음 두 코드의 결과는 동일하다.

async function f() {
  return 1;
}
f().then(alert); // 1
async function f() {
  return Promise.resolve(1);
}
f().then(alert); // 1

await

awaitasync 함수 안에서만 동작한다.
자바스크립트는 await를 만나면 promise가 처리될 때까지 기다리고, 처리되면 결과를 반환된다.

async function f() {
  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("완료!"), 1000)
  });
  let result = await promise; // 프라미스가 이행될 때까지 기다린다.
  alert(result);
}
f(); // 함수 호출

위 코드에서 await를 쓰지 않았을 경우,
promisesetTimeout 1초를 기다리지 않고 result에 담아 alert를 실행하기 때문에 alert창에는 "완료!"가 뜨지 않게된다.

awaitpromise가 처리될 때까지 async함수를 기다리게 한다.
promise가 처리가 완료되면 그 결과와 함께 함수 실행이 재개된다.
promise가 처리되길 기다리는 동안에 엔진이 다른 일을 할 수 있어 CPU 리소스가 낭비되지 않는다.


연습

https://velog.io/@esc/promise-chaining.then 대신 await/async 사용해보기

  • .then
let promise = fetch('https://jsonplaceholder.typicode.com/users/5')
  .then(response => response.json())
  .then(user => fetch(`https://api.github.com/users/${user.username}`))
  .then(response => response.json())
  .then(githubUser => new Promise(function(resolve, reject) {
    let img = document.createElement('img');
    img.src = githubUser.avatar_url;
    document.body.append(img);

    setTimeout(() => {
      img.remove();
      resolve(githubUser);
    }, 3000);
  }))
  .then(githubUser => console.log(`username: ${githubUser.login}`));
  1. .thenawait로 바꾼다.
  2. awaitasync함수로 감싼다.
  • await/async
async function showAvatar() {

  let response = await fetch('https://jsonplaceholder.typicode.com/users/5');
  let user = await response.json();

  let githubResponse = await fetch(`https://api.github.com/users/${user.username}`);
  let githubUser = await githubResponse.json();

  let img = document.createElement('img');
  img.src = githubUser.avatar_url;
  document.body.append(img);

  await new Promise((resolve, reject) => setTimeout(resolve, 3000));
  img.remove();

  return console.log(`username: ${githubUser.login}`);
}
showAvatar();

에러 핸들링

  • try..catch
    await가 던진 에러는 throw가 던진 에러를 잡을 때처럼 try..catch를 사용해 잡을 수 있다.
async function f() {
  try {
    let response = await fetch('http://유효하지-않은-주소');
  } catch(err) {
    alert(err); // TypeError: failed to fetch
  }
}
f();
  • 여러개의 await
    에러가 발생하면 제어 흐름이 catch 블록으로 넘어간다. 여러 줄의 코드를 try로 감싸는 것도 가능하다.
async function f() {
  try {
    let response = await fetch('http://유효하지-않은-주소');
    let user = await response.json();
  } catch(err) {
    // fetch와 response.json에서 발행한 에러 모두를 여기서 잡는다.
    alert(err);
  }
}
f();
  • .catch
    try..catch가 없으면 f().catch를 추가하면 거부된 promise를 처리할 수 있다.
async function f() {
  let response = await fetch('http://유효하지-않은-url');
}
// f()는 거부 상태의 프라미스가 된다.
f().catch(alert); // TypeError: failed to fetch

참조

https://ko.javascript.info/async-await

profile
front-end

0개의 댓글