[JavaScript] 비동기

뽀롱트옌드·2023년 10월 15일
0

JavaScript 심화(복습)

목록 보기
15/15
post-thumbnail

🏃🏻‍♀️ 비동기

[ 비동기, Asynchronous ]

- 동기와 비동기

  • 동기(Synchronous): 코드가 위에서 아래로 순차적으로 실행됨
  • 비동기(Asynchronous): 코드가 순차적으로 실행하지 않음
// 비동기
// 2가 먼저 출력되고 1은 1초후 코드실행
setTimeout(() => { console.log(1); }, 1000);
console.log(2);
console.log(3);

// 동기    
// 웹페이지를 실행하자마자 위에부터 순차적으로 실행됨
console.log(1);
console.log(2);

setTimeout함수가 위에 있지만 비동기함수라 1초뒤 실행하도록 설정해 놓아서 아래 코드인 2,3이 먼저 콘솔에 출력되고 1이 출력됨

- 콜백(Callback) 패턴

비동기 코드를 콜백패턴을 통해 실행순서를 지정(보장) 할 수 있음

// 비동기
// 서버(`https://www.omdbapi.com/?apikey=7035c60c&s=${movieName}`)가 응답을 하면 그때 코드가 실행됨
const getMovies = (movieName, callback) => {
  fetch(`https://www.omdbapi.com/?apikey=7035c60c&s=${movieName}`)
  .then(res => res.json())
  .then(res => {
     console.log(res);
     callback();
  })
}

getMovies('frozen', () => {
    console.log('겨울왕국!');
});
getMovies('disney', () => {
    console.log('디즈니💖');
});
getMovies('avatar', ()=>{
   console.log('아바타!'); 
});

서버로 겨울왕국->디즈니->아바타 순으로 처리요청했지만 서버에서 처리할 양이 겨울왕국이 디즈니나 아바타가 보다 많으면 처리 시간이 오래걸려 디즈니나 아바타가 겨울왕국보다 결과가 먼저 출력될수 있고 이는 서버의 처리속도에 따라 다르므로 매번 바뀔수있음

- 콜백(Callback) 지옥

  • 콜팩패턴으로 겨울왕국->디즈니->아바타 순으로 실행 순서 보장
  • 비동기함수를 콜백으로 넣어 순서를 명확하게 보장할수있지만 콜백으로만 제어하다보면 코드가 들여쓰기 형태로 계속 파고들어가 개미지옥처럼 코드 패턴이 만들어지는 것을 콜백지옥이라함
    • 콜백지옥의 단점은 가독성이 떨어지고 관리하기가 불편함
// 비동기 함수 생성
const getMovies = (movieName, callback) => {
  fetch(`https://www.omdbapi.com/?apikey=7035c60c&s=${movieName}`)
  .then(res => res.json())
  .then(res => {
     console.log(res);
     callback();
  })
}

// 콜백패턴으로 실행 순서 제어 -> 제어해야할 갯수가 더많아지면 코드가 계속 파고들어가 콜백지옥이됨
getMovies('frozen', () => {
    console.log('겨울왕국!');
    getMovies('disney', () => {
        console.log('디즈니💖');
        getMovies('avatar', ()=>{
            console.log('아바타!'); 
         });
    });
});

- Promise 클래스

  • 비동기 함수를 쉽게 제어하기 위해 콜백패턴을 쓰지만 길어지면 콜백이 생겨 코드가 복잡하기 때문에 Promise클래스를 사용함
  • Promise인스턴스를 반환하면(아래 코드에서 return키워드로 반환) 뒤쪽에.then` 메소드 사용가능

const a = () => {
  return new Promise((resolve) => {
    // 매개변수 resolve가 하나의 함수데이터를 받아서 호출함
    setTimeout(() => {
      console.log(1);
      resolve();
    }, 1000);
  });
};

const b = () => {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log(2);
      resolve();
    }, 1000);
  });
};

const c = () => console.log(3);

//  화살표 함수에서 return키워드가 바로가오면 {}와 return 키워드 생략가능
// Promise의 매개변수 resolve에 함수데이터만 전달해주면 됨 -> b, c, d는 함수데이터
// .then메소드는 체이닝 형식으로 계속 이어쓸수 있음 

a()
  .then(b)
  .then(c)
  .then(() => console.log('Done'));

콜백 예제 Promise로 변환


const getMovies = movieName => {
  return new Promise(resolve=> {
    fetch(`https://www.omdbapi.com/?apikey=7035c60c&s=${movieName}`)
    .then((res) => res.json())
    .then((res) => {
      console.log(res);
      resolve();
    });
  })
};

getMovies('frozen')
  .then(() => {
    console.log('겨울왕국!');
    return getMovies('disney');
  })
  .then(() => {
    console.log('디즈니💖');
    return getMovies('avatar');
  })
  .then(() => {
    console.log('아바타!');
  });

- Async / Await

  • async, await는 둘이 같이 써야 실행되는 짝꿍
  • async키워드가 붙어있는 함수 내부에서 await를 사용해야 실행됨
  • await: 뒤쪽에있는 비동기 코드를 기다렸다가 실행
  • Promise 인스턴트가 반환 되어야지만 호출됨(e.g. console.log 앞에 사용못함 -> 프로미스인스턴스를 반환하지 않기 때문)
const getMovies = movieName => {
  return new Promise(resolve=> {
    fetch(`https://www.omdbapi.com/?apikey=7035c60c&s=${movieName}`)
    .then((res) => res.json())
    .then((res) => {
      console.log(res);
      resolve();
    });
  })
};

const movieList= async () => {
  await getMovies('frozen');
  console.log('겨울왕국!')
  await getMovies('disney');
  console.log('디즈니💖');
  await getMovies('avatar');
  console.log('아바타!');
}
movieList();


🎮 패스트캠퍼스
프론트엔드 웹 개발의 모든 것 초격차패키지 Online.

profile
🎈 함께 성장하는 즐거운 개발자의 세계로! 🌈✨

0개의 댓글