[JS] async & await

O_K·2022년 3월 1일
1

Javascript

목록 보기
1/1
post-thumbnail

async & await

async function 함수명() {
  await 비동기_처리_메서드명();
}

비동기 처리 메서드 는 꼭 프로미스 객체를 반환해야한다

Promise

자바스크립트 비동기 처리를 위한 객체
비동기 작업의 단위
성공할 때는 resolve 함수를 호출, 실패할때는 reject 함수를 호출
resolve -> .then
reject -> .catch
ex) Axios: 프로미스를 반환하는 API 호출 함수

await 문법

awaitpromise.then보다 좀 더 세련되게 프라미스의 result 값을 얻을 수 있도록 해주는 문법

// await은 async 함수 안에서만 동작
// async 함수가 아닌 곳에서 await을 사용하면 에러가 발생
let value = await promise;

javascript는 await 키워드를 만나면 Promise가 처리(settled)될 때 까지 기다린다.
결과는 그 이후 반환

// 1초 후 이행되는 promise
async function f() {
  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("완료!"), 1000)
  });

  let result = await promise; // promise가 이행될 때 까지 기다림
  // promise가 이행돼서 resolve로 Promise.then 객체로 "완료!"를 반환할 때 까지 1초가 걸림
  // 이행완료되기까지 1초를 기다렸다가 result에 할당
  // => 즉 1초뒤에 완료! 가 alert됨
  alert(result); // "완료!"
}

setTimeout

setTimeout(기다린후 실행시킬 함수, 기다릴 밀리초, 콜백함수에 넣을 인자)
setTimeout은 비동기 처리함수이다.

function a(num) {
  console.log(num);
}

setTimeout(a, 2000, 1);
setTimeout(a, 1500, 2);
setTimeout(a, 1000, 3);

출력

3
2
1
  1. setTimeout 은 인자로 들어온 콜백 함수를 예약하기만 하고 바로 끝난다.
  2. setTimeout 에 의해 기다리는 동작은 본래의 코드 흐름과는 상관 없이 따로따로 독립적으로 돌아간다.
  3. 따로따로 독립적으로 돌아가는 작업 = 비동기 작업

Promise.then -> await 문법으로 바꿔보기

  1. .then 호출을 await으로 바꿔주기
  2. function 앞에 async를 붙이기

자세한 코드 설명

Promise.then 코드

// 3초간 아바타 이미지 보여주는 코드
// user.json에 요청을 보냅니다.
fetch('/article/promise-chaining/user.json')
  // 응답받은 내용을 json으로 불러옵니다.
  .then(response => response.json())
  // GitHub에 요청을 보냅니다.
  .then(user => fetch(`https://api.github.com/users/${user.name}`))
  // 응답받은 내용을 json 형태로 불러옵니다.
  .then(response => response.json())
  // 3초간 아바타 이미지(githubUser.avatar_url)를 보여줍니다.
  .then(githubUser => {
    let img = document.createElement('img');
    img.src = githubUser.avatar_url;
    img.className = "promise-avatar-example";
    document.body.append(img);

    setTimeout(() => img.remove(), 3000); // (*)
  });

async/await 코드

async function showAvatar() {

  // JSON 읽기
  let response = await fetch('/article/promise-chaining/user.json');
  let user = await response.json();

  // github 사용자 정보 읽기
  let githubResponse = await fetch(`https://api.github.com/users/${user.name}`);
  let githubUser = await githubResponse.json();

  // 아바타 보여주기
  let img = document.createElement('img');
  img.src = githubUser.avatar_url;
  img.className = "promise-avatar-example";
  document.body.append(img);

  // 3초 대기
  await new Promise((resolve, reject) => setTimeout(resolve, 3000));

  img.remove();

  return githubUser;
}

showAvatar();

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

왜 이러한 문법으로 작성하는가에 대해 의문이 생겨서 찾아보았다.

setTimeout은 Promise반환을 하지 않기 때문에 async와 await를 적용해도 동기적으로 적용되지 않는다고 한다.
따라서 Promise를 반환하게 직접 작성 후 async와 await를 적용해야한다고 한다.

Promise 생성자는 콜백을 인수로 받음
이 콜백의 첫 번째 인수로 resolve 함수가 들어오는데, 콜백 안에서 resolve를 호출하면
resolve에 인수로 준 값이 곧 Promise 객체의 궁극적인 결과값이 됨



일반 함수에서 async 함수 호출하기

async 함수를 호출하면 프라미스가 반환되므로, .then을 붙여 사용

async function wait() {
  await new Promise(resolve => setTimeout(resolve, 1000));

  return 10;
}

function f() {
  // shows 10 after 1 second
  wait().then(result => alert(result));
}

f();

참고

async/awat1
async/awat2
async/await3
비동기 프로그래밍
setTimeout + async/await
프로미스

profile
즐거운 개발자가 목표

1개의 댓글

comment-user-thumbnail
2022년 3월 4일

자바스크립트를 잘 몰랐는데 도움이 되었습니다 ~~ ^^

답글 달기