Lập trình Bất đồng bộ trong JavaScript
JavaScript là ngôn ngữ single-threaded, nhưng có thể xử lý nhiều tác vụ cùng lúc nhờ lập trình bất đồng bộ. Hãy cùng tìm hiểu Callback, Promise và Async/Await!
1. Callback Functions
Cách truyền thống nhất để xử lý bất đồng bộ:
// Callback đơn giản
function fetchData(callback) {
setTimeout(() => {
const data = { name: 'Huy', age: 22 };
callback(data);
}, 1000);
}
fetchData((data) => {
console.log(data); // Sau 1 giây
});
// Callback hell - vấn đề lớn
getData((a) => {
getMoreData(a, (b) => {
getEvenMoreData(b, (c) => {
getFinalData(c, (d) => {
console.log(d);
});
});
});
});
2. Promises
Promise giúp code dễ đọc hơn và tránh callback hell:
// Tạo Promise
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const success = true;
if (success) {
resolve({ name: 'Huy', age: 22 });
} else {
reject('Error fetching data');
}
}, 1000);
});
}
// Sử dụng Promise
fetchData()
.then(data => {
console.log(data);
return data.age;
})
.then(age => {
console.log('Age:', age);
})
.catch(error => {
console.error(error);
})
.finally(() => {
console.log('Done!');
});
3. Async/Await
Cú pháp hiện đại nhất, làm code bất đồng bộ trông như đồng bộ:
// Async function
async function getUserData() {
try {
// Await đợi Promise resolve
const user = await fetchUser();
const posts = await fetchPosts(user.id);
const comments = await fetchComments(posts[0].id);
return { user, posts, comments };
} catch (error) {
console.error('Error:', error);
}
}
// Gọi async function
getUserData().then(data => console.log(data));
// Hoặc trong async context khác
async function main() {
const data = await getUserData();
console.log(data);
}
main();
4. Promise.all() và Promise.race()
Xử lý nhiều Promise cùng lúc:
// Promise.all - đợi tất cả resolve
async function getAllData() {
const [users, posts, comments] = await Promise.all([
fetchUsers(),
fetchPosts(),
fetchComments()
]);
return { users, posts, comments };
}
// Promise.race - lấy kết quả nhanh nhất
async function getFastestData() {
const result = await Promise.race([
fetchFromServer1(),
fetchFromServer2(),
fetchFromServer3()
]);
return result; // Từ server nào respond nhanh nhất
}
5. Error Handling
Xử lý lỗi trong async code:
// Try-catch với async/await
async function safeDataFetch() {
try {
const data = await fetchData();
return data;
} catch (error) {
console.error('Failed to fetch:', error);
return null; // hoặc giá trị mặc định
}
}
// Catch cuối cùng
async function processData() {
const data = await fetchData();
const processed = await processData(data);
return processed;
}
processData()
.then(result => console.log(result))
.catch(error => console.error(error));
Kết luận
Lập trình bất đồng bộ là kỹ năng cần thiết trong JavaScript hiện đại:
- Callback: Cơ bản nhưng dễ gây callback hell
- Promise: Giải quyết callback hell, code cleaner
- Async/Await: Dễ đọc nhất, nên dùng trong code mới
Hãy thực hành với các API thực tế để thành thạo!