17. async, await

조뮁·2022년 8월 9일
0

JS중급

목록 보기
17/18
post-thumbnail

async

: 함수 앞에 async 키워드를 호출할 경우 항상 Promise를 반환함

  • promise 객체이기 때문에 async 함수 호출 후, .then() 사용 가능
async function getName() {
  return 'Mike';
}

console.log(getName());
/*
Promise {<fulfilled>: 'Mike'}
[[Prototype]]: Promise
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: "Mike"
*/
  • promise 객체를 반환하므로 .then 사용 가능
async function getName() {
  return 'Mike';
}

getName().then(name => {
  console.log(name);
});
// Mike
  • 반환값이 Promise면, Promise.resolve('Tom') 이라는 값을 그대로 사용 (?????)
async function getName() {
  return Promise.resolve('Tom');
}

getName().then(name => {
  console.log(name);
});
// Tom

질문

  • async 키워드 함수 내 'Mike'란 값을 바로 리턴해주는 것과, 반환값을 Promise로 주는 것은 무슨 차이가 있는지?
  • return 'Mike'를 해줄 경우, Promise 가 fulfilled 상태인데, 반환값을 Promise로 줄 경우 pending 상태임 (하단 promiseState 는 fulfilled가 되어있음....)

  • Promise 객체를 반환하는데 결과값으로 바로 Mike가 반환되었으니, Promise가 완료된 상태라고 표시되는건가?
  • 두번째는 Promise가 완료되면 실행될 callback resolve값을 Tom으로 설정해놓고 해당 Promise를 반환함. 그래서 promise는 대기상태라고 뜨고, 해당 Promise가 완료된 결과가 fulfilled / Tom 으로 나타나는것?
  • 예외발생 시 rejected 상태의 프로미스가 반환됨
async function getName() {
  throw new Error('err..');
}

// rejected는 catch 로 확인
getName().catch(err => {
  console.log(err)
});
// Error: err..

await

  • await 키워드는 async 함수 내부에서만 사용 가능
  • await 다음에는 Promise가 오고, 해당 Promise가 처리(완료)될 때 까지 기다린다.

async await를 쓰는 것이 Promise.then()을 사용하는 것 보다 가독성이 좋음.

function getName(name){
  return new Promise((res, rej) => {
    setTimeout(() => {
      res(name);
    }, 1500);
  });
}

async function showName(){
  const result = await getName('Mike');
  // result에 getName()에서 resolve된 값을 기다렸다가(await) 넣어줌
  console.log(result);
}

console.log('시작');
showName();
// 시작
// (1.5초 후) Mike

const f1 = () => {
  const apiResult = {
    score: 99,
    rating: 1,
  };
  return new Promise((res, rej) => {
    setTimeout(() => {
      res(apiResult);
    }, 1000);
  });
};

const f2 = (msg) => {
  console.log(msg);
  return new Promise((res, rej) => {
    setTimeout(() => {
      res('2번 요청 완료');
      // rej('xxx 2번 요청 실패 xxx');
    }, 500);
  });
};

const f3 = (msg) => {
  console.log(msg);
  return new Promise((res, rej) => {
    setTimeout(() => {
      res('3번 요청 완료');
    }, 2000);
  });
};

// async await 사용
async function order(){
  const result1 = await f1();
  // result2 변수에 f2(result1); 이 기다렸다가 들어가짐
  const result2 = await f2(result1);
  // result3 변수에 f3(result2); 이 기다렸다가 들어가짐
  const result3 = await f3(result2);
  console.log(result3);
  console.log('종료')
};

order();
// {score: 99, rating: 1}
// 2번 요청 완료
// 3번 요청 완료
// 종료

try ... catch

  • async await에서 rejected를 처리할 때 catch() 사용
  • catch 문에서 err 출력 후, 다음 작업으로 넘어감
    - (3번 작업은 시행되지 않음)
async function order(){
  try{
    const result1 = await f1();
    const result2 = await f2(result1);
    const result3 = await f3(result2);
    console.log(result3);
  }catch(err){
    console.log(err);
  }
  console.log('종료');
};

order();
// {score: 99, rating: 1}
// xxx 2번 요청 실패 xxx
// 종료
  • Promise.all 사용
    - async await 함수 내에서도 비동기함수를 병렬로 처리 가능
async function order(){
  try{
    const result = await Promise.all([f1(), f2(), f3()]);
    console.log(result)
  }catch(err){
    console.log(err);
  }
  console.log('종료');
};

order();
// [{score: 99, rating: 1}, '2번 요청 완료', '3번 요청 완료']

0개의 댓글