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:

Hãy thực hành với các API thực tế để thành thạo!