Callback hell là gì?
- ★
- ★
- ★
- ★
- ★
Trong lập trình bất đồng bộ (asynchronous programming) đặc biệt là trong ngôn ngữ lập trình (programming language) Javascript, callback hell còn được gọi là pyramid of doom là một anti-pattern, về cơ bản nó là các callback lồng nhau (nested callback) được xếp chồng lên nhau bên dưới tạo thành một cấu trúc kim tự tháp. Trong callback hell, mỗi và mọi callback nhận một đối số (argument) là kết quả của các callback trước đó. Mọi callback phụ thuộc / chờ đợi callback trước đó, do đó tạo ra một cấu trúc kim tự tháp ảnh hưởng đến khả năng đọc (readability) và khả năng bảo trì (maintainability) của mã. Ngoài ra, nếu có lỗi trong một hàm (function), thì tất cả các hàm khác sẽ bị ảnh hưởng.
Trong ví dụ dưới đây, chúng ta đã chia từ GeeksForGeeks thành ba từ riêng biệt và đang cố gắng tạo hoạt ảnh (animate) cho từng từ sau từ khác.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible"
content="IE=edge">
<meta name="viewport" content=
"width=device-width, initial-scale=1.0">
<title>Callback Hell</title>
<style>
* {
padding: none;
margin: none;
box-sizing: border-box;
}
.word {
color: #308d46;
font-size: 4rem;
transition: all .5s ease-in;
margin: 0 5px;
transform: translateY(3.8rem);
opacity: 0;
}
body {
display: flex;
justify-content: center;
align-items: center;
width: 95vw;
height: 95vh;
}
.container {
overflow: hidden;
display: flex;
flex-direction: row;
}
.animate {
opacity: 1;
transform: translateY(0);
}
</style>
</head>
<body>
<div class="container">
<h2 class="word">Geeks</h2>
<h2 class="word">For</h2>
<h2 class="word">Geeks</h2>
</div>
</body>
<script>
let words = document.querySelectorAll(".word");
const animateAll = (animate) => {
setTimeout(() => {
animate(words[0]);
setTimeout(() => {
animate(words[1]);
setTimeout(() => {
animate(words[2]);
}, 1000)
}, 1000)
}, 1000)
}
const animate = (word) => {
word.classList.add("animate");
}
animateAll(animate);
</script>
</html>
Chúng ta có thể nhận thấy rằng hàm animateAll có cấu trúc kim tự tháp, do đó khiến nó khó đọc.
Output:
Làm thế nào để thoát khỏi callback hell?
- JavaScript cung cấp một cách dễ dàng để thoát khỏi callback hell. Điều này được thực hiện bởi hàng đợi sự kiện (event queue) và các promise.
- Một promise là một đối tượng (object) được trả về (return) từ bất kỳ hàm không đồng bộ (asynchronous function) nào, mà các hàm callback (callback function) có thể được thêm vào dựa trên kết quả của hàm trước đó.
- Promise sử dụng phương thức (method) .then() để gọi các callback không đồng bộ (async callback). Chúng ta có thể nối (chain) bao nhiêu callback tùy thích và thứ tự (order) cũng được duy trì nghiêm ngặt.
- Promise sử dụng phương thức .fetch() để tìm nạp một đối tượng từ mạng (network). Nó cũng sử dụng phương thức .catch() để bắt (catch) bất kỳ ngoại lệ (exception) nào khi bất kỳ khối (block) nào bị lỗi.
- Vì vậy, những promise này được đưa vào hàng đợi sự kiện để chúng không chặn (block) mã JS tiếp theo. Ngoài ra khi kết quả được trả về, hàng đợi sự kiện sẽ kết thúc hoạt động của nó.
- Ngoài ra còn có các từ khóa (keyword) và phương thức hữu ích khác như async, wait, settimeout() để đơn giản hóa và sử dụng tốt hơn các callback.
Learning English Everyday