개념 정리_동기(Sync)&비동기(Async), Promise, 비동기 함수(Async Function)

정윤숙·2024년 3월 21일
1

TIL

목록 보기
190/192
post-thumbnail

📒 오늘의 공부

1. 동기(Sync)&비동기(Async), Promise, 비동기 함수(Async Function)

Node.js 입문 강의 내용 중 개념 정리

1. 동기(Sync)&비동기(Async)

  • 동기(Sync)

    • 먼저 실행된 코드의 결과가 나올 때까지 대기한 후 다음 코드 실행
  • 비동기(Async)

    • 먼저 실행된 작업의 완료를 기다리지 않고 실행된 순서와 관계 없이 다음 코드가 즉시 실행

2. Blocking Model & Non-Blocking Model

  • 차단 모델(Blocking Model)

    • 작업이 완료될 때까지 실행 제어권을 다른곳에 넘기지 않아 프로그램이 멈추는 것
    • 제어권을 넘기지 않으면(Blocking) 비동기 처리가 가능한 환경이어도 비동기 처리가 불가능
  • 비차단 모델(Non-Blocking Model)

    • 작업이 완료될 때까지 기다리지 않고 실행 제어권을 다른곳에 넘겨 다른 작업을 수행할 수 있는것
    • 제어권을 넘기면(Non-blocking) 다른 코드도 실행될 수 있으므로 비동기 처리가 가능
  • Javascript는 Async + Non-Blocking Model을 채용하여 현재 실행중인 코드의 실행이 끝나지 않아도 다음 코드를 호출

    • Javascript는 각 명령들이 순서대로 실행될 수 있게 구현되어 있지만, Non-Blocking Model에 의해 모든 함수는 비동기적으로 실행

3. Promise

  • Javascript에서 비동기 처리를 동기로 처리할 수 있게 돕는 객체


    💡 동기 처리가 필요한 이유

    • 데이터를 가져온 후 데이터를 가공해야 할 때
      • 비동기처리를 하는 Javascript에서는 데이터를 가져오기도 전에 데이터 가공 명령이 실행
      • 이 때 Promise를 사용하게 되면 데이터 가공 명령을 Promise 이후에 실행되도록 할 수 있다.

  • Promise의 상태

    • 대기(Pending): 이행하거나 거부되지 않은 초기 상태
    • 이행(Fulfilled): 성공적으로 연산 완료
    • 거부(Rejected): 연산 실패
  • Promise 구문

    new Promise(executor)
    • new 키워드를 사용하여 Promise 객체 생성

    • Promise의 실행 함수라고 불리는 executor는 Promise가 만들어지는 즉시 자동으로 호출된다.

    • executorresolvereject라는 두 개의 콜백 함수를 받는다.

    • resolve

      • Promise가 성공적으로 이행됐을 때 호출되는 함수
      • 이 함수를 호출하면 Promise는 이행(Fulfilled) 상태가 된다.
      • 이 값은 Promise가 이행될 때 then() 메서드로 전달된다.
    • reject
      - Promise가 실패했을 때 호출되는 함수
      - 이 함수를 호출하면 Promise는 거부(Rejected) 상태가 된다.
      - 이 값은 Promise가 거부될 때 catch() 메서드로 전달된다.

      const promise = new Promise((resolve, reject) => {
            // 비동기 작업 수행
            if (/* 성공 조건 */) {
                resolve("작업 성공!");
            } else {
                reject("작업 실패!");
            }
        });
      
      promise.then((result) => {
        console.log("작업 성공:", result); 
      }).catch((error) => {
        console.error("작업 실패:", error); 
      });
      
    • then() 메서드

      • Promise가 이행(Fulfilled)됐을 때 호출될 콜백 함수를 등록
      • 성공적으로 resolve된 경우에 호출
    • catch() 메서드

      • Promise가 거부(Rejected)됐을 때 호출될 콜백 함수를 등록
      • reject된 경우에 호출

      => promise 객체가 이행되면 then() 메서드에 전달된 콜백 함수가 호출되어 "작업 성공!"이라는 결과를 출력하고, 거부되면 catch() 메서드에 전달된 콜백 함수가 호출되어 "작업 실패!"라는 에러를 출력

  • Promise를 사용하는 경우

    • 네트워크 요청: 서버로부터 데이터를 가져오거나 데이터를 전송할 때
    • 파일 읽기/쓰기: 파일 시스템에서 데이터를 읽거나 쓸 때
    • 타이머 함수: setTimeout 또는 setInterval과 같은 비동기적인 타이머 함수를 사용할 때

4. 비동기 함수 (Async Function)

  • JavaScript에서 비동기 작업을 처리하는 데 사용되는 기능

  • 특징

    • 비동기 함수의 결과 값항상 Promise 객체로 resolve된다.
    • 비동기 함수 안에서만 await 연산자를 사용할 수 있다.
  • await 연산자

    • async 함수의 실행을 일시 중지하고 전달 된 Promise의 해결을 기다린 다음 async 함수의 실행을 다시 시작하고 완료후 값을 반환
    • await 연산자는 비동기 함수 내에서 비동기적으로 처리되는 작업을 동기적으로 작동하도록 만들어주는 역할
function resolveAfter2Seconds() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve('resolved');
    }, 2000);
  });
}

async function asyncCall() {
  console.log('calling');
  const result = await resolveAfter2Seconds();
  console.log(result);
  // Expected output: "resolved"
}

asyncCall();
  • 실행 결과
    • 'calling'이 출력되고 2초 후 Promise와 'resolved' 반환

5. 비동기 함수(Async Function)와 Promise 비교

  • Promise chain은 연속된 then() 및 catch() 호출을 통해 비동기 작업을 처리하고 에러를 처리하기 때문에 복잡한 비동기 로직을 표현하기에는 적합하지 않을 수 있다.
function fetchData() {
    return fetch('https://api.example.com/data')
        .then(response => {
            if (!response.ok) {
                throw new Error('데이터를 가져오는 데 실패했습니다.');
            }
            return response.json();
        })
        .then(data => {
            console.log('데이터를 성공적으로 가져왔습니다:', data);
        })
        .catch(error => {
            console.error('에러 발생:', error);
        });
}
  • 비동기 함수(Async Function)는 코드를 선언적으로 작성할 수 있으며, 비동기 작업의 흐름을 보다 명확하게 표현할 수 있다.
    • await 연산자를 사용하여 비동기 작업의 완료를 기다린다. 이로써 코드의 흐름이 명확해지고, 비동기 작업을 일련의 동기식 코드처럼 보다 자연스럽게 작성할 수 있다.
    • try-catch 문을 사용하여 에러를 처리하므로, 에러 처리도 용이하다.
async function fetchData() {
    try {
        const response = await fetch('https://api.example.com/data');
        if (!response.ok) {
            throw new Error('데이터를 가져오는 데 실패했습니다.');
        }
        const data = await response.json();
        console.log('데이터를 성공적으로 가져왔습니다:', data);
    } catch (error) {
        console.error('에러 발생:', error);
    }
}

참고자료

profile
프론트엔드 개발자

0개의 댓글