Javascript 비동기 처리 [Promise, async, await]

Nine·2022년 2월 24일
2

Javascript

목록 보기
5/16
post-thumbnail

🤔우리 자바스크립트는요.. 우리 맘대로 안 돌아가요

동기적(Synchronous)

자바스크립트는 동기적(Synchronous) 언어입니다.

  • 한 번에 하나의 작업을 수행해요.

  • 키오스크를 이용하여 한 사람씩 결제하는 느낌이랄까요?

  • 이러한 동작을 단일 스레드(싱글 스레드), 동기(Synchronous)라고 해요.

  • Hoisting 된 후 작성한 순서에 맞춰 동기적으로 실행됩니다.

    잠깐 Hoisting??
    
        - 코드가 실행하기 전 var, function declaration이 제일 위로 올라가요.
        
        - 변수선언 / 함수선언 이 해당 스코프의 최상단으로 끌어 올려진 것 같은 현상을 말해요.

비동기(asynchronous)

  • 어떠한 요청을 보내면 그 요청이 끝날 때까지 기다리는 것이 아니라, 응답에 관계없이 바로 다음 동작이 실행되는 방식을 말해요.

🤔왜 비동기가 필요한가요?

  • 웹 페이지가 로딩되거나, 어떠한 동작(Event) 하나가 30초 이상이 걸린다고 상상해봐요

  • 동기적으로 하면 웹 페이지는 이 동작이 끝날 때까지 화면에 나타나지 않거나 다음 동작을 수행하는데 지장을 주게 됩니다.

  • 또, 사용자들은 빠른 응답을 주는 웹 사이트를 원하죠?

  • 그렇기 때문에 자바스크립트가 웹 사이트에서 동작할 때, 비동기적으로 동작할 수 있어야 해요.


⚙️비동기 동작 원리

  1. Call Stack에서 비동기 함수가 호출되면 Call Stack에 먼저 쌓였다가 Web API(혹은 백그라운드라고도 한다)로 이동한 후 해당 함수가 등록되고 Call Stack에서 사라진다.
  1. Web API(백그라운드)에서 비동기 함수의 이벤트가 발생하면, 해당 콜백 함수는 Callback Queue에 push(이동) 된다.
  1. 이제 Call Stack이 비어있는지 이벤트 루프(Event Loop)가 확인을 하는데 만약 비어있으면, Call Stack에 Callback Queue에 있는 콜백 함수를 넘겨준다.(push)
  1. Call Stack에 들어온 함수는 실행이 되고 실행이 끝나면 Call Stack에서 사라진다.
  • 사실 이 부분은 영상 자료를 참고하는게 이해가 제일 빠를 거라고 생각합니다.

💪Promise

  • 비동기 동작을 다루는 하나의 패턴이예요.

어떤 일의 진행 상태를 나타내는 객체로 진행 상태와 값이라는 속성을 가지고 있어요.

  • 진행 상태 : pending → fulfilled or rejected

  • resolve, reject는 함수입니다.

const promise = new Promise((resolve, reject)=>{
	// doing heavy work
	// 성공 시 
		resolve("성공했어요.");
	// 실패 시
		reject(new Error('실패했어요.'));
});

promise
	.then(value => console.log(value)) // resolve를 받음
	.catch(err => console.log(err)); //reject를 받음

💪async

  • Promise를 깔끔하게 사용할 수 있어요.

  • new Promise 객체를 사용하지 않아도 Promise를 반환해요.

Promise인 경우

function fetchUser() {
  //10초씩이나 걸리는 작업;
  return new Promise((resolve,reject)=>{
    resolve('나인');
  })
}

fetchUser().then((who)=>console.log(who))
console.log('두두등장');

async로 바꾼 경우

async function fetchUser() {
  // 10초씩이나 걸리는 작업;
  return '나인';
}

fetchUser().then((who)=>console.log(who));
console.log('두두등장');

💪await

  • async가 붙은 함수 내에서만 쓸 수 있어요.

  • 동기 함수든 비동기 함수든 앞에 붙일 수 있어요.

  • await키워드를 앞에 붙이면 해당 함수가 실행을 끝낼 때까지 다음 코드는 동작하지 않아요.

  • 아래는 MDN 예시예요.

Promise만 쓰면..

// then으로 자꾸 콜백을 해야해요ㅠㅠ
fetch('coffee.jpg')
.then(response => response.blob())
.then(myBlob => {
  let objectURL = URL.createObjectURL(myBlob);
  let image = document.createElement('img');
  image.src = objectURL;
  document.body.appendChild(image);
})
.catch(e => {
  console.log('There has been a problem with your fetch operation: ' + e.message);
});

async / await를 쓰면..

// await는 async가 붙은 함수 내에서만 쓸수 있다고 했죠?
async function myFetch() { 
  let response = await fetch('coffee.jpg'); // 오래 걸리니 기다려 주세요.
  let myBlob = await response.blob(); // 오래 걸리니 기다려 주세요.

  let objectURL = URL.createObjectURL(myBlob);
  let image = document.createElement('img');

  image.src = objectURL;
  document.body.appendChild(image);
}

// 호출해볼까요.
myFetch()
.catch(e => {
  console.log('There has been a problem with your fetch operation: ' + e.message);
});
  • 훨씬 간단해졌죠?
profile
함께 웃어야 행복한 개발자 장호영입니다😃

0개의 댓글