async, await / TIL 2021.06.12

leitmotif·2021년 6월 11일
0

🧐 async & await

async는 function 내에 비동기적으로 실행될 것이 있다고 명시한다.

await은 선언된 코드의 객체가 값을 반환할 때까지 기다린다.
이 때, await는 async function에서만 사용할 수 있다.

async function은 실행 중 await를 만나게되면 scope가 잠시 외부로 변경된다.
외부에 있는 코드들이 실행된 뒤, await 뒤의 Promise 객체 상태를 기다린다.


개요

async function fetchAndPrint(){
  const response = 
  	await fetch('https://jsonplaceholder.typicode.com/users');
  const result = await response.text();
  console.log(result);
}

fetchAndPrint();

예제의 경우, fetch가 완료되면 그 이후에 response 작업이 진행된다.

위의 예제코드는 fetch로도 표현할 수 있다.

fetch(url)
	.then((res) => {
    	return response.text();
    })
    .then((result) => {console.log(result);});

즉 async + await은 Promise chaining을 더 간소화하여 표현할 수 있게끔 한다.

간혹 뛰어난 가독성으로 인해 async function이 promise 객체를 포함하고 있다는 것을 잊지 않도록 하자...

뿐만 아니라 promise 객체를 반환하는 코드에 대해서 꼭 await를 붙일 것.


📂 async function의 catch & finally

async function에서는 try~catch 블록을 사용한다.

const p1 = fetch('https://jsonplaceholder.typicode.com/users?id=1')
  .then((response) => response.text());
const p2 = new Promise((resolve, reject) => {
  setTimeout(() => { resolve('hello'); }, 2000);
});
const p3 = Promise.resolve('Success');
const p4 = Promise.reject(new Error('Fail'));

async function test() {
	try{
    	console.log(await p1);
        console.log(await p2);
        console.log(await p3);
        console.log(await p4);
     } catch (err) {
     	console.log(err);
     } finally {
     	console.log('exit');
     }
}

딱히 어려운 개념없이 통상적인 예외처리문과 같다.


📂 여러가지 async function

async function test1() {
  const result = await Promise.resolve('success');
  console.log(result);
}

async function test2() {
  try {
    const p = new Promise((resolve, reject) => {
      setTimeout(() => { resolve('last'); }, 3000);
    });
    const result = await p;
    console.log(result);
  } catch (e) {
    console.log(e);
  }
}

async function test3() {
  try {
    const result = await Promise.reject('fail');
    console.log(result);
  } catch (e) {
    console.log(e);
  }
}

test1();
console.log('JavaScript');
test2();
console.log('Programming');
test3();

위와 같이 async function이 많은 경우, 일단 외부 코드가 모두 실행된 뒤
await를 만난 순서대로 Promise 객체가 작업된다.

다만 test2가 3초 이후에 발생하기에 가장 늦으므로

JavaScript -> Programming -> Success -> fail -> last

순서로 출력될 것이다.


📂 async의 즉시 실행

async function이라면 await된 Promise 객체의 작업 완료를 기다려야 되지만..

(async function print(sentence) {
  console.log(sentence);
  return sentence;
}('Test'));

(async function (a, b) {
  return a + b;
}(1, 2));

(async (a, b) => {
  return a + b; 
})(1, 2);

(async (a, b) => a + b)(1, 2);

위의 예제코드처럼 소괄호로 한번 감싸준 경우 즉시 실행이 가능하다.

async 코드의 성능 이슈에 대해 사용 가능하다.
예를 들면, response의 순서가 상관이 없다거나..?


🎯 특이사항

async function은 그 자체로 Promise 객체를 반환한다.

async function fetchAndPrint() {
  return new Promise((resolve, reject)=> {
    setTimeout(() => { resolve('abc'); }, 4000);
  });
}

fetchAndPrint();

위처럼 Promise 객체를 리턴으로 명시하면 fulfilled 또는 rejected 상태 결과가 반환되며

async function fetchAndPrint() {
  return 3;
}

fetchAndPrint();

또는 Promise가 아닌 객체를 반환하면 fulfilled 상태로, 결과 값이 3인 Promise 객체가 반환된다.

async function fetchAndPrint() {
  
}

fetchAndPrint();

만약 위와 같이 내부에 아무 내용도 없다면, undefined가 반환되고

async function fetchAndPrint() {
  throw new Error('Fail');
}

fetchAndPrint();

에러가 발생한다면 당연히 rejected 상태의 Promise 객체가 반환된다.

async function이 Promise 객체를 반환한다는 것에 착안하여
async 내부에 async function을 쓰기도 한다.


대략적인 JS Topic 공부는 여기서 마무리.

하지만 아직 포스팅해야할 것은 많다.

  1. DOM
  2. Event Bubbling
  3. this
  4. Object literal, Factory function, constructor function
  5. http vs https
  6. REST API
  7. Response status code 정리
  8. ajax와 axios // 공부가 필요한 부분

다음 주는 ssafy 면접이 있다.

주말은 면접 준비를, 그 후엔 차근차근 React 학습을 시작하며
간단한 로그인 페이지를 만들어볼 생각이다.

profile
제가 그린 것으로 하여금, 동기를 일으키는 개발자가 되고 싶습니다.

0개의 댓글