async/await

최혜린·2025년 3월 12일
  • async/await는 비동기 프로그래밍을 간결하고 직관적으로 작성할 수 있도록 도와주는 기능이다.
  • 기존에 사용하던 콜백 함수나 Promise 체이닝(.then())보다 가독성이 뛰어나다.

콜백함수?
콜백 함수는 특정 시점에 실행될 함수를 인자로 전달하는 패턴으로 비동기 프로그래밍에서 자주 사용되는 함수이나 중첩될수록 코드의 가독성과 유지보수성이 떨어지는 문제가 있다. 이에 대해서는 나중에 자세히 써야겠다.. ✍️

// 콜백 함수 사용
function step1(callback) {
    setTimeout(() => {
        console.log("1단계 완료");
        callback();
    }, 1000);
}

function step2(callback) {
    setTimeout(() => {
        console.log("2단계 완료");
        callback();
    }, 1000);
}

function step3(callback) {
    setTimeout(() => {
        console.log("3단계 완료");
        callback();
    }, 1000);
}

//으으.. 갚어질수록 디버깅과 유지보수가 어렵다.. ! 
step1(() => {
    step2(() => {
        step3(() => {
            console.log("모든 단계 완료");
        });
    });
});
// async/await로 개선
async function runSteps() {
    await step1();
    await step2();
    await step3();
    console.log("모든 단계 완료");
}
// 편-안

갑자기 이야기가 콜백 함수로 갔는데.. 위와 같은 이유로
콜백 함수보다는 async/await를 사용함으로 코드를 더 직관적이게 만들 수 있다

async/await 기본 개념

1.async

  • 함수 앞에 async를 붙이면 자동으로 Promise를 반환하는 비동기 함수가 된다.
  • async function 내부에서 await를 사용할 수 있다.

2.await

  • await를 사용하면 비동기 작업이 완료될 때까지 기다렸다가 결과를 반환한다.
  • await는 async 함수 내부에서만 사용 가능하다.
async function fetchData() {
    let response = await fetch("https://jsonplaceholder.typicode.com/posts/1");
    let data = await response.json();
    console.log(data);
}

fetchData();
await fetch(url) → API 요청이 완료될 때까지 기다림.
await response.json() → 응답을 JSON 형태로 변환.

async/await 장점

  1. 앞에서 설명한 콜백함수의 단점인 콜백 지옥을 해결할 수 있다.
  2. 가독성이 뛰어나다.
  3. try-catch를 사용하여 에러처리를 쉽게할 수 있다.
async function fetchData() {
    try {
        let response = await fetch("https://jsonplaceholder.typicode.com/posts/1");
        let data = await response.json();
        console.log(data);
    } catch (error) {
        console.error("오류 발생:", error);
    }
}

fetchData();

여러 비동기 작업을 동시에 실행하는 방법

위와 같은 장점에서도 순차적으로 실행하면 성능이 저하되는게 아닐까 하는 걱정이 든다.. 면!
Promise.all()을 활용하면 된다. 여러개의 await를 병렬로 실행할 수 있다.

async function fetchMultipleData() {
    let [user, posts] = await Promise.all([
        fetch("https://jsonplaceholder.typicode.com/users/1").then(res => res.json()),
        fetch("https://jsonplaceholder.typicode.com/posts?userId=1").then(res => res.json())
    ]);

    console.log("사용자 정보:", user);
    console.log("사용자의 게시글:", posts);
}

fetchMultipleData();
Promise.all()을 사용하여 두개의 await를 병렬로 실행하여 속도를 개선하였다

그러나 Promise.all에도 치명적 단점이 존재하니..!
하나라도 실패하면 전체가 실패한다는 단점이 있다.

이를 해결하기 위해Promise.allSettled()을 사용하여 보자..

romise.allSettled()는 여러 개의 Promise를 병렬로 실행하고, 모든 Promise가 완료될 때까지 기다린 후 각 Promise의 성공(fulfilled) 또는 실패(rejected) 상태를 반환하는 메서드이다.


Promise.allSettled() 사용 예제

async function fetchData() {
    let results = await Promise.allSettled([
        fetch("https://jsonplaceholder.typicode.com/users/1").then(res => res.json()),
        fetch("https://wrong-url.typicode.com/").then(res => res.json()), // 존재하지 않는 URL
        fetch("https://jsonplaceholder.typicode.com/posts/1").then(res => res.json())
    ]);

    console.log("📌 모든 요청 결과:", results);
}

fetchData();

출력 예시

[
  { "status": "fulfilled", "value": { "id": 1, "name": "Leanne Graham", ... } },
  { "status": "rejected", "reason": "TypeError: Failed to fetch" },
  { "status": "fulfilled", "value": { "userId": 1, "id": 1, "title": "sunt aut facere repellat ..." } }
]

🔹 언제 Promise.allSettled()을 사용해야 할까?

상황Promise.all()Promise.allSettled()
여러 요청을 병렬로 실행해야 하는 경우✅ 가능✅ 가능
하나라도 실패하면 전체 실패해야 하는 경우✅ 추천❌ 비추천
일부 실패해도 나머지를 처리해야 하는 경우❌ 비추천✅ 추천
각 요청의 성공/실패 여부를 개별적으로 확인해야 하는 경우❌ 비추천✅ 추천

주의해야 할 점은 await는 async 함수 내부에서만 사용 가능하다는 점이다 ,,!

몇번이나 까먹고 실수했던 과거 ..😂
어싱크 어웨이트! 잊지말자 !!..

profile
산으로 가는 코딩.. 등산 중..🌄

0개의 댓글