하위 태스크 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
}
]
]