하위 태스크 1

async.js 생성

비동기 실습용 JS 파일 생성

async.js:

console.log("A");
 
setTimeout(() => {
    console.log("B");
});
 
console.log("C");

Node.js에서 async.js를 실행한다.

node async.js

실행 결과는 다음과 같으며 브라우저에서 실행해도 결과는 동일하다.

A
C
B

하위 태스크 2 ~ 6

동기/비동기 순서 실험

console.log + setTimeout 조합으로 순서 확인

Node.js 환경에서 실행

node async.js 로 실행해 브라우저와 비교

콜백 기반 fetchUser 구현

1초 뒤 사용자 정보 콜백으로 전달

콜백 기반 fetchPosts 구현

사용자 ID로 게시글 목록 콜백 전달

콜백 지옥 흐름 구현

사용자 → 게시글 순서로 중첩 콜백 작성

async.js:

// ...
 
const users = [
    {
        id: 0,
        name: "홍길동",
        age: 10,
    },
    {
        id: 1,
        name: "김철수",
        age: 21,
    },
]
 
const posts = [
    {
        id: 0,
        title: "Awesome things",
        body: "These are awesome!",
        userId: 0,
    },
    {
        id: 1,
        title: "I'm happy today",
        body: "I ate great foods.",
        userId: 1,
    },
    {
        id: 2,
        title: "I work hard yesterday",
        body: "I'm so tired.",
        userId: 0,
    },
    {
        id: 3,
        title: "JavaScript is a great language",
        body: "Do you agree ?",
        userId: 1,
    },
];
 
function fetchUser(callback) {
    const user = users[Math.round(Math.random())];
 
    setTimeout(() => {
        callback(user);
    }, 1000);
}
 
function fetchPosts(userId, callback) {
    return setTimeout(() => {
        const ownPosts = posts.filter((post) => post.userId === userId);
        callback(ownPosts);
    }, 1000);
}
 
fetchUser((user) => {
   fetchPosts(user.id, (posts) => {
        console.log(posts);
    }); 
});

Node.js에서 async.js를 실행한 결과는 다음과 같다. 브라우저에서 실행한 결과 또한 같다. (단, fetchUser가 매번 다른 사용자 객체를 반환하기 때문에 실행할 때마다 결과가 달라질 수 있다.)

# ...
[
  {
    id: 0,
    title: 'Awesome things',
    body: 'These are awesome!',
    userId: 0
  },
  {
    id: 2,
    title: 'I work hard yesterday',
    body: "I'm so tired.",
    userId: 0
  }
]

하위 태스크 7 ~ 8

Promise 기반으로 변환

fetchUser/fetchPosts를 Promise 반환으로 변경

then 체인 구현

.then() 으로 비동기 흐름 재구성

async.js:

function fetchUser() {
    const user = users[Math.round(Math.random() * users.length)];
 
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(user);
        }, 1000);
    });
}
 
function fetchPosts(userId) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (userId === undefined) {
                reject(new Error("유효하지 않은 사용자 ID입니다."));
                return;
            }
 
            const ownPosts = posts.filter((post) => post.userId === userId);
            resolve(ownPosts);
        }, 1000);
    });
}
 
fetchUser()
    .then((user) => fetchPosts(user?.id))
    .then((posts) => { console.log(posts); })
    .catch((error) => { console.error(error.message); });

결과는 이전 하위 태스크와 같다.

하위 태스크 9 ~ 10

async·await 구현

async 함수 안에서 await로 흐름 구현

에러 처리 로직 추가

reject/throw와 .catch() /try-catch로 에러 처리

async.js:

// ...
 
async function main() {
    try {
        const user = await fetchUser();
        const posts = await fetchPosts(user?.id);
        console.log(posts);
    } catch (error) {
        console.error(error.message);
    }
}
 
void main();

결과는 이전 하위 태스크와 같다.

하위 태스크 11

Promise.all 병렬 처리

여러 Promise를 동시에 실행하는 예제 작성

async.js:

// ...
 
async function fetchPostsByUserId(userId) {
    try {
        const user = await fetchUser();
        const posts = await fetchPosts(user?.id);
        return posts;
    } catch (error) {
        console.error(error.message);
        return [];
    }
}
 
async function main() {
    const promises = [fetchPostsByUserId(0), fetchPostsByUserId(1)];
    console.log(await Promise.all(promises));
}
 
void main();
# ...
[
  [
    {
      id: 1,
      title: "I'm happy today",
      body: 'I ate great foods.',
      userId: 1
    },
    {
      id: 3,
      title: 'JavaScript is a great language',
      body: 'Do you agree ?',
      userId: 1
    }
  ],
  [
    {
      id: 1,
      title: "I'm happy today",
      body: 'I ate great foods.',
      userId: 1
    },
    {
      id: 3,
      title: 'JavaScript is a great language',
      body: 'Do you agree ?',
      userId: 1
    }
  ]
]