STUDY/[ JavaScript ]

Async/ Await/ Top-Level Await/ Promise/ Callback/ 동기,비동기 작업

Lim임 2025. 10. 1. 02:49

코파일럿이

top level await은 큰 문제인걸~ 하고 수정해줬다

뭔소린지 도통 모르겠어서 처음부터 차근차근 

 

왜 수정했는지 뭐가 문제인지 탐구해봤다

 

일단 동기식 비동기식이 먼지 알면 조음

📌 동기 코드 (Synchronous)
한 줄씩 순서대로 실행하고, 끝날 때까지 기다림

console.log('1번'); 
console.log('2번'); 
console.log('3번'); 
// 결과: 1번 → 2번 → 3번 (순서대로!)

 

📌 비동기 코드 (Asynchronous)
기다리지 않고 다음 줄로 넘어감

console.log('1번');
setTimeout(() => console.log('2번'), 1000); // 1초 후 실행
console.log('3번');
// 결과: 1번 → 3번 → (1초 후) 2번 (순서가 뒤바뀜!)

 

그래서 생기는 문제점이 

중간에 가져오는 시간을 기다려주지 않음!

console.log('1. 쿼리 시작!');
const data = connection.query('SELECT * FROM users'); // 0.1초 걸림
console.log('2. 쿼리 끝?'); // ❌ 아직 안 끝남!
console.log(data); // Promise 객체만 나옴

를 await을 통해  기다려준다함~~~

 

await 이란 기다려!!!! 라는 뜻

비동기 작업이 끝날 때까지 기다리라는 명령임

 

Database 쿼리문은 시간이 걸리는 작업이라서

작업이 끝날 때까지는 기다려주는게 인지상정임

 

await을 넣어주면 :

console.log('1. 쿼리 시작!');
const data = await connection.query('SELECT * FROM users'); // 0.1초 기다림
console.log('2. 쿼리 진짜 끝!'); // ✅ 진짜 끝남!
console.log(data); // 실제 데이터 나옴!

 

근데 얘도 단점이 있음!!

 

가장 상단에서 await( top level await ) 하는게 좋지 않다구 코드를 수정해줬다

 

Top-Level Await 하게되면

// 모듈 로드와 동시에 실행됨
const data = await fetchData(); // ⚠️ 위험!
  • 모듈을 import 할 때 바로 실행됨 
  • 다른 모듈들이 이 모듈을 기다려야 함!
  • 모듈 로드 시점에 에러가 발생하면 전체 앱이 멈춘다!!

그래서 Async Function 방식을 권장한대

// 필요할 때만 실행
async function fetchDataWhenNeeded() {
  try {
    const data = await fetchData(); // ✅ 안전!
    return data;
  } catch (err) {
    console.log('에러 처리:', err);
    return null;
  }
}

// 실행할 때
fetchDataWhenNeeded();

export { fetchDataWhenNeeded };

이렇게 되면

  • 호출 시점을 제어할 수 있다
  • 에러 처리가 용이하다
  • 모듈 로딩 속도가 향상된다

암튼 짱 좋다는 거임!!

 

그리고 async 없이 await하면 오류가 발생함(다고 함)

🚫 async 없이 await 사용하면:

// ❌ 오류 발생!
function getData() {
  const result = await connection.query('SELECT * FROM users');
  // JS엔진: "await? 근데 이 함수가 비동기인지 어떻게 알아? 오류!"
}

 

왜 오류가 나냐면

async는 이런 일을 해요

  • 이 코드는 비동기야!! 라고 JavaScript에게 안내함
  • await을 사용할 수 있게 허가도 내려줌
  • 함수를 자동으로!! Promise로 감싸줌 (async를 붙이면 자동으로 Promise를 반환함!! )
    • async function asyncFunction() {
        return "Hello";
      }
      console.log(asyncFunction()); // Promise { "Hello" }

✅ async를 붙이면:

async function getData() {
  //    ↑ 
  // JS엔진: "아! 이 함수는 비동기구나. await 사용 OK!"
  const result = await connection.query('SELECT * FROM users');
  //            ↑
  // JS엔진: "여기서 기다리고, 결과가 나오면 다음 줄 실행할게!"
}

내부에서는 이런 일이 일어나는 거임

// 우리가 쓰는 코드:
async function getData() {
  const user = await getUser();
  const posts = await getPosts(user.id);
  return { user, posts };
}

// JavaScript가 내부적으로 변환한 코드 (대략):
function getData() {
  return new Promise((resolve, reject) => {
    getUser()
      .then(user => {
        return getPosts(user.id)
          .then(posts => {
            resolve({ user, posts });
          });
      })
      .catch(reject);
  });
}

 

Promise 로 감싸주고 .then() 형식을 써줌!! 고맙다 async야!!!

 

 

await이 없는 옛날에는 Callback 방식으로만 처리해서 콜백지옥에 갇혔다고 함

( Promise 방식와 callback 방식의 차이도 여기 중간에 짧게 적어놓긴 했음 )

 

Callback 방식 :

connection.query('SELECT * FROM users', (err, users) => {
  if (err) throw err;
  connection.query('SELECT * FROM posts', (err, posts) => {
    if (err) throw err;
    connection.query('SELECT * FROM comments', (err, comments) => {
      if (err) throw err;
      // 드디어 사용 가능... 😵
    });
  });
});

넣고오류잡고 넣고오류잡고 넣고오류잡고 넣고오류잡고 넣고오류잡고 

이래서 지옥이었다 함

 

Promise 방식에서는 .then을 사용해서

connection.query('SELECT * FROM users')
  .then(users => {
    return connection.query('SELECT * FROM posts');
  })
  .then(posts => {
    return connection.query('SELECT * FROM comments');
  })
  .then(comments => {
    // 사용 가능
  })
  .catch(err => console.log(err));

음 가독성이 마니 조아졌슴 내눈엔 머가 다른지는 모르겠으나

어쨌든 마니쓰면 얘도 지옥인데

 

Async를 쓰면 자동으로 Promise로 묶어주기 떄문에 해결~~!!

async function getAllData() {
  try {
    const users = await connection.query('SELECT * FROM users');
    const posts = await connection.query('SELECT * FROM posts');  
    const comments = await connection.query('SELECT * FROM comments');
    
    // 깔끔하게 사용! 😊
    return { users, posts, comments };
  } catch (err) {
    console.log(err);
  }
}

 

결론: 

async는 JavaScript 엔진에게 "이 함수에서 await 써도 돼!" 라고 허가증을 주는 것입니다! 🎫✨

 

좋은 친구네요^^ 짝짝짝