Full-stack Developer chuyên về Java Backend và JavaScript Frontend. Sẵn sàng đóng góp vào các dự án web development với kỹ năng vững chắc và tinh thần học hỏi không ngừng.
Mục lục
Mục lục
🚀 Khám phá bí mật đằng sau JavaScript Async Programming - từ Callbacks cổ điển đến Async/Await hiện đại, master Event Loop và viết code non-blocking như một pro!
Tại sao cần học Async? JavaScript là single-threaded nhưng có thể xử lý hàng ngàn operations đồng thời! Bí mật nằm ở Event Loop và Asynchronous Programming.
JavaScript là single-threaded (đơn luồng) nhưng có thể xử lý các tác vụ bất đồng bộ (asynchronous) nhờ vào:
Call Stack: Nơi thực thi code đồng bộ
Web APIs: setTimeout, fetch, DOM events
Callback Queue: Hàng đợi callbacks
Event Loop: Kiểm tra và chuyển callbacks từ queue vào stack
// Synchronous - blocking code
console.log("Start");// Giả sử API call mất 3 giây
constdata=fetchDataFromAPI();// BLOCKING!
console.log(data);console.log("End");// Phải chờ 3 giây mới chạy
// Asynchronous - non-blocking
console.log("Start");fetchDataFromAPI((data)=>{console.log(data);// Chạy sau khi có data
});console.log("End");// Chạy ngay, không chờ
// setTimeout - async function
setTimeout(()=>{console.log("Chạy sau 2 giây");},2000);console.log("Chạy ngay lập tức");// Output:
// "Chạy ngay lập tức"
// (sau 2 giây) "Chạy sau 2 giây"
// Async function luôn return Promise
asyncfunctionfetchData(){return"Data";}fetchData().then(data=>console.log(data));// "Data"
// Await chỉ dùng trong async function
asyncfunctiongetData(){constdata=awaitfetchData();// Chờ Promise resolve
console.log(data);}getData();
// Fetch data from API
asyncfunctionfetchGitHubUser(username){try{console.log(`Fetching data for ${username}...`);constresponse=awaitfetch(`https://api.github.com/users/${username}`);if(!response.ok){thrownewError(`User not found! Status: ${response.status}`);}constuser=awaitresponse.json();console.log("User Info:");console.log(`- Name: ${user.name}`);console.log(`- Bio: ${user.bio}`);console.log(`- Public Repos: ${user.public_repos}`);console.log(`- Followers: ${user.followers}`);returnuser;}catch(error){console.error("Error fetching user:",error.message);throwerror;}}// Fetch multiple users
asyncfunctionfetchMultipleUsers(usernames){try{constpromises=usernames.map(username=>fetch(`https://api.github.com/users/${username}`).then(res=>res.json()));constusers=awaitPromise.all(promises);users.forEach(user=>{console.log(`${user.name}: ${user.public_repos} repos`);});returnusers;}catch(error){console.error("Error fetching users:",error);}}// Usage
fetchGitHubUser("torvalds");fetchMultipleUsers(["torvalds","gvanrossum","BrendanEich"]);
🔄 Event Loop Magic: Đây là “trái tim” của JavaScript async - hiểu Event Loop = hiểu cách JS hoạt động!
graph TD
A[Call Stack] --> B{Stack Empty?}
B -->|Yes| C[Check Microtask Queue]
C --> D{Has Microtasks?}
D -->|Yes| E[Execute Microtasks]
E --> A
D -->|No| F[Check Macrotask Queue]
F --> G{Has Macrotasks?}
G -->|Yes| H[Execute One Macrotask]
H --> A
G -->|No| B
style A fill:#ff6b6b
style C fill:#4ecdc4
style F fill:#45b7d1
// ❌ Bad - không handle error
asyncfunctionbadFetch(){constdata=awaitfetch(url);returndata.json();}// ✅ Good - handle error
asyncfunctiongoodFetch(){try{constdata=awaitfetch(url);returnawaitdata.json();}catch(error){console.error("Fetch failed:",error);throwerror;}}
// ❌ Bad - nested async
asyncfunctionbad(){constuser=awaitgetUser();if(user){constposts=awaitgetPosts(user.id);if(posts.length>0){constcomments=awaitgetComments(posts[0].id);returncomments;}}}// ✅ Good - early return
asyncfunctiongood(){constuser=awaitgetUser();if(!user)returnnull;constposts=awaitgetPosts(user.id);if(posts.length===0)returnnull;returnawaitgetComments(posts[0].id);}