[Javascript] 비동기

Jane Yeonju Kim·2022년 3월 14일
1

JavaScript

목록 보기
13/14

비동기 / 동기를 왜 알아야 할까요? 그 이유는

1. 서버에서 결과값을 잘 받아오도록 & 오류를 처리하기 위해서
2. 생각하는 순서대로 실행시키기 위해서라고 생각합니다.

자바스크립트의 비동기 특성을 잘 이해하기 위해서는 서버와의 통신, Promise 객체에 대한 이해가 필요합니다.


자바스크립트는 비동기적인 특성을 갖습니다.
특정 코드의 연산이 끝나지 않더라도 다음 코드를 실행하는 것을 말하고,
자바스크립트는 코드를 단순하게 순서대로 실행하지 않는 것을 의미합니다.


서버와 통신하는 시간 생각하기

function getData() {
  	let data
    fetch("데이터가 있는 곳 주소")
      .then((res) => res.json())
      .then((res) => 
            data = res
            // console.log(data)
           );
	return data
}

console.log(getData())

이렇게 작성하면 fetch함수가 데이터가 있는 곳 주소를 찾아가서 데이터를 잘 가져오고 getData함수의 반환값을 콘솔에 찍어보면 결과가 잘 나타날 것 같은데요!

실제로는 undefined를 반환합니다.
데이터를 잘못 받아왔나싶어서 콘솔에 data변수를 찍어보면 결과값이 잘 나옵니다!

왜 이런 일이 일어날까요?

그 이유는 자바스크립트를 실행할 때 비동기적으로 실행되어서
fetch함수가 데이터를 가져올 때까지 기다려 주지 않고 data를 바로 반환해버렸기 때문입니다.


참고한 블로그: 캡틴판교님의 명쾌한 비동기와 콜백함수 설명
비동기 이해하기: 유튜버 얄코님 비동기 영상

fetch()

..그런데 fetch함수는 뭘까요?
fetch함수는 네트워크에서 리소스를 가져오는 함수입니다!

fetch("리소스를 가져올 주소", 옵션)으로 사용할 수 있습니다.
옵션부분에 method, header, body 등 HTTP통신에 필요한 정보들을 담아서 처리할 수 있습니다. 옵션부분이 비워져 있다면 기본적으로 method는 GET으로 처리됩니다.

MDN fetch API


Promise 객체

Promise 객체는 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타냅니다.
출처: MDN Promise

위에서 사용한 fetch함수의 반환값으로 Promise객체가 반환됩니다.
Promise 객체는 3 가지 상태중 하나의 상태를 갖습니다.

  • 대기(pending): 이행하지도, 거부하지도 않은 초기 상태.
  • 이행(fulfilled): 연산이 성공적으로 완료됨.
  • 거부(rejected): 연산이 실패함.

굉장히 어려워 보이지만.. 네트워크 통신을 아직 안 한건지 / 성공했는지 / 실패했는지 상태를 바로 알 수 있게 객체 형태로 담았다고 생각하시면 됩니다.

연산에 성공한 fulfilled Promise 객체는 .then함수로 값을 받아 올 수 있습니다.
실패한 rejected Promise 객체는 .catch함수로 오류를 처리할 수 있죠.


async & await

await 문이 없는 async 함수는 동기적으로 실행됩니다.
하지만 await 문이 있다면 async 함수는 항상 비동기적으로 완료됩니다.
출처: MDN async function

fetch함수와 .then함수를 이용해서 Promise Chain을 길게 만들면 한눈에 로직을 이해하기가 어렵습니다.

하지만 async함수와 await함수를 이용하면 훨씬 이해하기도 쉽고 사용하기도 쉽습니다!

// Promise Chain
function getProcessedData(url) {
  return downloadData(url)
    .catch(e => {
      return downloadFallbackData(url)
    })
    .then(v => {
      return processDataInWorker(v)
    })
}


// async & await
async function getProcessedData(url) {
  let v;
  try {
    v = await downloadData(url);
  } catch (e) {
    v = await downloadFallbackData(url);
  }
  return processDataInWorker(v);
}

같은 내용이지만
async와 await함수를 이용해서 try, catch구문으로
통신에 성공하면 downloadData함수를 비동기적으로 실행하고,
통신에 실패하면 downloadFallbackData함수를 비동기적으로 실행한다는 것이
한눈에 보이지 않나요?

await함수가 async함수 안에서만 사용된다는 점은 주의해야 합니다!


profile
안녕하세요! 김개발자입니다 👩‍💻 🐈

2개의 댓글

comment-user-thumbnail
2022년 3월 15일

연주님 덕분에 자바스크립트 비동기 방식에 대한 개념 정리가 잘 되었습니다! 중간에 참고할만한 블로그나 영상이 같이 있어 이해하기 좋았어요👍

1개의 답글