[JS] 비동기가 뭘까 async / await

최예준·2023년 11월 26일

공부

목록 보기
5/19

자바스크립트는 말 잘 안드뤠.... 🤤🤤

자바스크립트는 동기적 이다

우리 자바스크립트는요?...

  • 한 번에 하나의 작업을 수행할 수 있어요
  • Hoisting 된 이후 작성한 순서에 맞춰서 동기적으로 실행되요
  • 정말 차례차례 수행한답니다

그럼 비동기가 뭘까?

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

왜 필요할까요?

아래 사진을 봐요

딱봐도 비동기가 효율적이고 빠르죠?

고로 웹사이트가 동작할 때는 비동기 적으로 동작할 수 있어야 해요.

동작원리를 알아볼까요?

일단 보고오세요 >

  1. Call Stack에서 비동기 함수가 호출되면 Call Stack에 먼저 쌓였다가 Web API(혹은 백그라운드라고도 한다)로 이동한 후 해당 함수가 등록되고 Call Stack에서 사라진다.

  2. Web API(백그라운드)에서 비동기 함수의 이벤트가 발생하면, 해당 콜백 함수는 Callback Queue에 push(이동) 된다.

  3. 이제 Call Stack이 비어있는지 이벤트 루프(Event Loop)가 확인을 하는데 만약 비어있으면, Call Stack에 Callback Queue에 있는 콜백 함수를 넘겨준다.(push)

  4. 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를 받음

단 promise 는 polyfill 등의 라이브러리 없이는 익스플로어에서 동작하지 않는다!!

💪async

es7 에서는
Promise를 깔끔하게 사용할 수 있어요.

new Promise 객체를 사용하지 않아도 Promise를 반환해요.
(사실 이거쓰면 new 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('두두등장');

하지만 then 으로 콜백 하기 귀찮으니 하나만 더 알아보자구요..!

💪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개의 댓글