프론트엔드

동기,비동기 / promise & async/await

zayn 2024. 10. 21. 17:42

[ 용어설명 ]

  • 동기 : 작업이 순차적으로 처리되며, 이전 작업이 완료될 떼까지 다음 작업을 시작하지 않는 방식
  • 비동기 : 작업이 병렬적으로 처리되어, 결과를 기다리지 않고 다른 작업을 동시에 처리할 수 있는 방식
  • 논블로킹 : 작업이 실행되는 동안 다른 작업의 진행을 막지 않는 방식. 비동기 작업을 통해 구현됨
  • 이벤트 루프 : 자바스크립트의 비동기 작업을 관리하고, 콜백 큐에 있는 작업을 콩 스택에 추가해 실행하는 매커니즘
  • 프로미스 : 비동기 작업의 성공 또는 실패를 나타내는 자바스크립트 객체로, 비동기 작업의 결과를 처리하는 데 사용됨
  • async / await : 프로미스를 보다 직관적으로 처리할 수 있게 해주는 자바스크립트 구문으로, 비동기코드를 동기 코드처럼 작성할 수 있게 함.

[ 학습내용 ] 

 

 

  • 동기

동기 방식은 요청을 보낸 후 결과를 기다리는 방식

하나의 작업이 끝나야만 다음 작업을 시작할 수 있음.

여러요청을 동시에 처리할 수 없다.

요청의 순서에 따라 처리됨.

ex) 작업 1이 완료되어야 작업 2 시작.

console.log("손님1 커피 주문");
console.log("손님1 커피 제조 시작");
console.log("손님1 커피 제조 완료");

console.log("손님2 커피 주문");
console.log("손님2 커피 제조 시작");
console.log("손님2 커피 제조 완료");

 

 

  • 비동기

비동기 방식은 요청을 보낸 후 응답을 기다리지 않는 방식

다른작업을 동시에 처리 할 수 있는 방식

비동기는 순차적인 처리가 아닌, 동시에 여러 요청을 처리 할 수 있다는 점

→ 비효율적인 대기 시간을 줄이고 시스템 자원을 더 효과적으로 사용 할 수 있음.

but! 응답의 도착 시점은 예측할 수 없기 때문에 적절한 콜백 함수나 프로미스를 사용하여 응답을 처리해야함.

 

console.log("손님1 커피 주문");
console.log("손님1 커피 제조 시작");
setTimeout(() => {
	// 손님1 커피 제조 진행중...
  console.log("손님1 커피 제조 완료");
}, 2000); // 2초 후에 실행

console.log("손님2 커피 주문");
console.log("손님2 커피 제조 시작");
// ...

setTimeout은 2초후에 실행 되지만, 그동안 다른작업이 계속해서 진행

 

▶ JS를 커피숍에 비유해서 생각하면 쉬움.

동기 프로그래밍은 코드가 실행되면 그 자리에서 결과가 바로 나와야하므로 다음 코드의 실행을 막고 실행되게된다.

 

★ 자바스크립트는 Non-Blocking I/O 를 가진 비동기를 지원하는 언어.

 

  • Non-Blocking I/O

- I/O 는 input/output 을 뜻함.

 

  • Blocking
function blockingTask() {
  const start = Date.now();
  // 3초 동안 블로킹
  while (Date.now() - start < 3000) {
    // 시간이 지나기만을 기다립니다.
  }
  console.log("블로킹 작업 완료");
}

console.log("작업 시작");
blockingTask();
console.log("작업 완료");

 

▶ 블로킹 작업은 현재 실행 중인 코드가 완료 될때까지 다음 코드의 실행을 멈추게 함.

▶ 동기코드에서 흔히 발생

▶ 블로킹 작업이 완료될 때 까지 프로그램의 다른 부분이 중단되므로, 긴 작업이 있으면 전체 프로그램의 성능이 저하될수있음.

 

  • Non Blocking
function nonBlockingTask() {
  setTimeout(() => {
    console.log("논블로킹 작업 완료");
  }, 3000);
}

console.log("작업 시작");
nonBlockingTask();
console.log("작업 완료");

▶ 논 블로킹 작업은 다른 코드의 실행을 멈추지 않는다.

▶ 작업이 비동기적으로 처리되어, 긴 작업이 실행되는 동안에도 프로그램의 다른 부분이 계속 실행.

▶ 논블로킹 이벤트 루프를 통해 처리

 

  • 이벤트 루프

- 비동기 코드는 동기 코드들이 모두 완료된 이후에 실행된다.

 

[ Promise, async/await ]

 

Promise와 async/await 는 비동기작업을 보다 직관적이고 효율적으로 처리할 수 있게 해주는 도구

 

  • Promise

▶ 프로미스는 자바스크립트에서 비동기 작업의 완료 또는 실패를 나타내는 객체.

 

프로미스의 3가지 상태

 

  1. 대기중 : 아직 결과를 받지 못한 상태.
  2. 이행됨 : 작업이 성공적으로 완료된 상태.
  3. 거부됨 : 작업이 실패한 상태

 

  • 프로미스 생성

▶ 프로미스는 new Promise를 통해 생성할 수 있습니다.

생성자 함수는 두 가지 콜백 함수를 매개변수로 받습니다. : resolve와 reject

 

 

  • 프로미스 사용

▶ 프로미스는 then과 catch 메서드를 사용하여 결과를 처리합니다.

 

  • 프로미스 체이닝

▶ 여러 비동기 작업을 순차적으로 실행할 때 프로미스 체이닝을 사용할 수 있다.

▶ then 메서드는 새로운 프로미스를 반환해서 체이닝을 가능하게 만들어준다.

▶ catch를 사용하면 프로미스의 결과가 실패 일 때 (에러발생시) 에러를 잡아서 처리 할 수 있게 한다.

 

  • async/await

▶ async/await는 프로미스를 더 간단하게 사용할 수 있게 해줌. 

▶ 이둘은 거의 똑같음

▶ syntax sugar = 문법적인 설탕이라고 함

 

  • async 함수

▶ async 함수는 항상 프로미스를 반환

▶ 함수 내부에서 return되는 값은 자동으로 Promise를 반환하게 되어서 Promise.resolve() 를 통해 감싸진다.

 

async function myAsyncFunction() {
  return "Hello, Async!";
}

myAsyncFunction().then(result => {
  console.log(result); // "Hello, Async!"
});

 

  • await 키워드

▶ 프로미스가 해결될 때까지 비동기 함수의 실행을 일시 중지.

▶ await 는 오직 async 함수내에서만 사용할 수 있다.

 

async function fetchData() {
  const response = await fetch("~");
  const data = await response.json();
  console.log(data);
}

fetchData();

 - 비동기 함수의 내부로직을 동기 함수 처럼! 보이게끔 만들어준다.

 

  • 에러 핸들링

▶ async/await 에서도 에러 처리는 try...catch문 사용

async function fetchData() {
  try {
    const response = await fetch("~");
    if (!response.ok) {
      throw new Error("네트워크 응답이 올바르지 않습니다.");
    }
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error("에러 발생:", error);
  }
}

fetchData();

 

  • async/await 장점
  1.  가독성 향상 : 비동기 코드를 동기 코드처럼 작성할 수 있어 가독성이 올라간다.
  2. 디버깅 용이 : 프로미스 체이닝보다 디버깅이 더 쉽다.
  3. 직관적 에러 처리 : try... catch를 사용한 에러 처리가 직관적입니다.

Q. 무조건 async/await 를 쓰는게 좋은거 아니야?

 

A : 대부분 OK but.  피치못하게 then() 등의 체이닝을 통해 표현해야할 일이 있다.

 

  • 여러 비동기 작업 한방에 처리하기

- 여러 비동기 작업을 동시에 처리하고 그 결과를 기다릴 때는 Promise.all과 함께 사용할 수 있다.

 

 

 

'프론트엔드' 카테고리의 다른 글

CODE_DAY3  (0) 2024.11.01
CODE_DAY 1  (0) 2024.10.30
동기 비동기관련 코드  (0) 2024.10.22
프론트엔드 002  (0) 2024.09.06
프론트엔드 001  (6) 2024.09.05