JavaScript

[JavaScript] 비동기

wwxs 2024. 8. 12. 01:43

비동기(async)

비동기 프로그래밍

  •  특정 코드의 실행 완료를 기다리지 않고 다음 코드를 실행하는 프로그래밍 방식
  • 프로그램의 실행 흐름을 차단하지 않고, '시간이 오래 소요'되는 작업 처리에 사용
  • ex) '네트워크 요청(서버와의 통신)', 파일 I/O 등에 주로 사용
더보기
console.log('== 비동기 구현 ==');
function anotherWork() {
  setTimeout(() => {
    const start = Date.now();

    for (let i = 0; i < 9999999999; i++) {} 
  
    const end = Date.now();
    console.log(end - start + 'ms');
  }, 0);
}

console.log('비동기 작업 시작');
anotherWork();
console.log('비동기 작업 완료 후 실행'); // 비동기 작업 완료 전 실행

 

비동기 프로그래밍 - 콜백 함수

  • 다른 함수에 인자로 전달되어, 해당 함수에 의해 어느 시점에 호출되는 함수
더보기
// 콜백함수
function greet(name) {
  console.log(`Hello, ${name}`);
}
더보기
// 메인 함수
function getUserInput(callback) {
  let name = prompt('이름을 입력해주세요.');
  callback(name);
}

getUserInput(greet);

 

콜백 함수를 사용하는 비동기 요청 예시

더보기
function fetchUserData(userId, callback) {
  // 시간에 대한 소요: setTimeout() 함수를 사용 구현
  setTimeout(() => {
    // 서버로 부터 가져온 데이터 (가정)
    const userData = {
      // 가상의 사용자 데이터
      id: userId,
      name: '홍동현',
      email: 'shifttag'
    };

    // 사용자의 데이터를 받아온 후에 작업할 콜백 함수
    callback(userData);
  }, 3000);
}

// 사용자 데이터 처리 함수(콜백 함수)
function handleUserData(user , callback) {
  console.log(`User Data: ${user.name}`);

  // 콜백함수 내에서 함수 실행 후 동작시킬 코드
  // : 중첩된 콜백함수
  callback();
}

fetchUserData(1, handleUserData); // 비동기 처리 로직

console.log('비동기적인 출력'); // 메인 로직

 

콜백 함수의 중첩 : 콜백 지옥(callback hell)

  • Promise 기반의 비동기 처리 프로그래밍을 통한 방지
더보기
function a() {
  console.log('a');
  function b() {
    console.log('b');
    function c() {
      console.log('c');
    }
  }
}

 

자바스크립트 비동기 프로그래밍 - Promise(프로미스)

  • 비동기 작업의 완료 또는 실패를 나타내는 '객체'
  • 콜백 지옥을 피하고, 비동기 처리에 대한 가독성 향상
  • 현재는 알 수 없지만, 나중에 결과를 나타낼 수 있는 값

상태

1) 대기(pending)

  • 초기 상태, 비동기 연산이 완료되지 X

2) 이행(fullfilled)

  • 비동기 연산이 성공(완료) → 프로미스가 결과값을 반환한 상태

3) 거부(rejected)

  • 비동기 연산이 실패 → 프로미스가 에러를 반환한 상태

 

Promise 생성 및 사용법 (기본구조)

  • new Promise(생성자를 사용하여 생성)
  • 해당 생성자는 실행 함수를 인자로 전달받음
  • 실행함수는 resolve와 reject의 두 가지 매개변수를 가짐
더보기
const myPromise = new Promise((resolve, reject) => {
  // 비동기로 수행될 작업을 작성
  const condition = true;

  if (condition) { // 작업 성공의 조건
    // 성공에 대한 로직
    resolve('프로미스 성공!!');
  } else {
    // 실패에 대한 로직
    reject('프로미스 실패ㅠㅠ');
  }
});

myPromise
  .then((result) => {
    console.log(result);
    return '다음 수행 시 필요한 데이터';
  })
  .then((nextResult) => {
    console.log(nextResult);
    return '세 번째 작업';
  })
  .then((thirdResult) => {
    console.log(thirdResult);
  })
  .catch((error) => {
    console.error(error);
  })
  .finally(() => {
    console.log('무조건 실행');
  });

 

프로미스 메서드 사용

  • new Promiose()를 통해 생성된 프로미스 객체 내부의 메서드

1) . then()

  • 프로미스 이행 시 호출: resolve를 받음
더보기

cf) 인자값 2개를 받음

  • 첫 번째: 이행, 두 번째: 거부

2) .catch()

  • 프로미스 거부 시 호출: reject를 받음 (오류 관리)

3) .finally()

  • 성공/실패 여부와 상관 없이 실행될 콜백 함수 등록

 

더보기
(프로미스 예시 (프로미스 체이닝 & 에러 핸들링))

function fetchData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => resolve('데이터 가져오기 성공'), 3000);
  }); // 프로미스 객체 반환
}

// 데이터 처리하기 
function processData(data) {
  return new Promise((resolve, reject) => {
    setTimeout(() => resolve(`${data} 사용하기`), 3000);
  });
}

// then, catch 필수
fetchData()
  .then(result => processData(result)) // 3초
  .then(processResult => console.log(processResult)) // 3초
  .catch(error => console.error(error));

console.log('메인 로직의 실행 (시간이 많이 걸리지 않는 작업)');

 

자바스크립트 비동기 프로그래밍 - async(비동기적인) / await(기다리다)

 

async 함수

  • 함수 자체를 비동기 함수로 정의하는 키워드
  • async function 함수명() {}
  • 항상 Promise 객체를 반환

await 함수

  • async 함수 내부에서 await 키워드를 사용
  • Promise의 결과를 기다림
더보기
(async await 비동기 예시)

async function fetchUserData() {
  // fetch('url')함수
  // : 해당 url을 사용하여 서버와 통신을 하는 메서드
  // >> Response 객체를 반환

  let data = await fetch('https://api.example.com/data'); // 시간이 걸리는 작업

  let jsonData = await data.json();

  console.log(jsonData);
}

'JavaScript' 카테고리의 다른 글

[JavaScript] 예외(exception)  (0) 2024.08.13
[JavaScript] DOM  (0) 2024.08.13
[JavaScript] 모듈  (0) 2024.08.11
[JavaScript] 내장 객체  (0) 2024.08.08
[JavaScript] 이벤트(Event)  (0) 2024.08.07