Download as rtf, pdf, or txt
Download as rtf, pdf, or txt
You are on page 1of 7

Callback hell là gì?

6 cách “trị” callback hell trong javascript

1533

Bài viết được sự cho phép của tác giả Sơn Dương

Chắc hẳn những bạn nào quen lập trình Nodejs hay Javascript rồi thì khái niệm Callback không còn xa lạ
nữa. Nhưng với người mới như mình thì callback hell trong javascript luôn là một ám ảnh. Vậy Callback
hell là gì? Nó có hay xảy ra khi làm việc với Nodejs không?

Mình phải thừa nhận một điều là mình quyết định học Nodejs chẳng qua bị sếp ép mà thôi. Với xuất
phát điểm từ lập trình Java, cho đến lập trình Android nên tư duy xử lý bất đồng bộ của Javascript thực
sự làm mình bối rối.

Như mọi người cũng biết, việc xử lý các tác vụ trong Javascript là bất đồng bộ. Tức là các tác vụ sẽ được
Javascript đẩy hết một event loop.

Các bạn có thể xem video bên dưới để hiểu rõ hơn về Event Loop trong Javascript nhé.

Tác vụ nào hoàn thành thì sẽ được bắn sự kiện để thông báo và trả kết quả. Do đó các tác vụ sẽ không
được thực hiện theo đúng trình tự như chúng ta nhìn trong code.

Từ đó, chúng ta sử dụng callback để có thể điều khiển việc thực hiện các tác vụ theo đúng trình tự mong
muốn.

Tuy nhiên, nếu lạm dụng callback mà không được thiết kế cẩn thận sẽ làm cho code của bạn trở lên khó
đọc, khó bảo trì.

Callback hell là gì? 6 cách "trị" callback hell trong javascript dễ nhất

#Callback hell trong javascript là gì?


Chắc hẳn bạn đang rất muốn biết bản chất callbackhell trong javascript là gì đúng không?

Thực ra callback hell trong javascript chỉ là bạn thực hiện quá nhiều callback lồng nhau. Đại khái, callback
hell sẽ có hình dạng như bên dưới.

getData(function(a){

getMoreData(a, function(b){

getMoreData(b, function(c){

getMoreData(c, function(d){

getMoreData(d, function(e){

...

});

});

});

});

});

Xem tiếp...

Nhìn qua đoạn code bạn có thấy khiếp không?

Những người mới bắt đầu học Nodejs thường rất dễ bị lỗi này. Đơn giản vì các bạn chưa có một tư duy
thiết kế chuẩn cho kiểu hệ thống hướng sự kiện.

Bài viết này, mình sẽ chia sẻ 5 cách để các bạn hạn chế bị callback hell trong javascript mà dễ thực hiện
nhất.

Xử lý bất đồng bộ với Promise.all trong JavaScript


12 Thư viện JavaScript trực quan hoá dữ liệu hot nhất năm 2023

#6 cách xử lý callback hell trong javascript dễ nhất

1. Thiết kế ứng dụng theo dạng module

Cũng giống với các ngôn ngữ lập trình khác, một trong những cách để hạn chế sự phức tạp của code là
module hóa.

Bất cứ khi nào bạn viết code, đừng cắm cổ vào viết ngay mà hãy dành một chút thời gian để suy nghĩ
xem mình viết như này đã tốt nhất chưa.

Bạn đang viết một đoạn code và đoạn code này xuất hiện ở rất nhiều nơi? Hay các phần của đoạn code
đó lại đang có vẻ tái sử dụng được… Lúc này bạn hãy mạnh dạn nghĩ tới module hóa nó.

Bạn nên nhớ rằng, Nodejs được như ngày hôm nay là do được xây dựng trên hàng trăm ngàn modules
khác nhau. Nodejs sẽ không là gì cả nếu không có các module. Nên việc bạn module mã nguồn của mình
là đi đúng hướng với triết lý của Nodejs đấy.

Ví dụ cách viết một module. Bạn tạo một module tên là Test.

//node_modules/test/index.js

module.exports = {

hello: function(name) {

console.log("Hello, " + name);

},

bye: function(name) {

console.log("Goodbye, " + name);

}
};

Xem tiếp...

Sau đó gọi ở ứng dụng như sau:

var greeter = require('test');

greeter.hello("Monkey");

greeter.bye("Steven");

Việc làm JavaScript Hồ Chí Minh dành cho bạn!

2. Nên đặt tên cho callback trong javascript

Bạn hay bắt gặp cách viết callback là các hàm anonymous function. Tức là các hàm không có tên.

Ví dụ một đoạn code sử dụng callback là anonymous function. Và có đến 2 callback lồng nhau.

var fs = require('fs');

var myFile = '/tmp/test';

fs.readFile(myFile, 'utf8', function(err, txt) {

if (err) return console.log(err);

txt = txt + '\nAppended something!';

fs.writeFile(myFile, txt, function(err) {

if(err) return console.log(err);

console.log('Appended text!');
});

});

Xem tiếp...

Nhìn vào đoạn code này sẽ khiến bạn mất vài giây để xem callback thực hiện điều gì và được gọi từ đâu.

Để khắc phục điều này, đơn giản bạn thêm một thao tác nhỏ là đặt tên cho callback. Nó sẽ giúp bạn dễ
đọc code hơn, đặc biệt khi các callback lồng nhau nhiều hơn.

var fs = require('fs');

var myFile = '/tmp/test';

fs.readFile(myFile, 'utf8', function appendText(err, txt) {

if (err) return console.log(err);

txt = txt + '\nAppended something!';

fs.writeFile(myFile, txt, function notifyUser(err) {

if(err) return console.log(err);

console.log('Appended text!');

});

});

Xem tiếp...

Lúc này, bạn chỉ cần lướt qua là biết callback đầu tiên thực hiện việc nối các text lại với nhau. Còn
callback thứ 2 là để thông báo cho người người dùng. Việc này giúp bạn tránh được callback hell trong
javascript dễ dàng đúng không?

>> Có ích cho bạn: Tự xây dựng ứng dụng web với ExpressJS
3. Định nghĩa hàm trước khi gọi để tránh callback hell trong javascript

Vẫn với ví dụ ở trên, việc bạn đặt tên đã giúp cho code dễ đọc hơn rất nhiều. Nhưng nó vẫn còn khá
cồng kềnh.

Bạn thực hiện thêm một bước nữa, đó là tách riêng và định nghĩa các callback riêng ra. Hãy cứ tách hàm
khi có thể!

var fs = require('fs');

function notifyUser(err) {

if(err) return console.log(err);

console.log('Appended text!');

};

function appendText(err, txt) {

if (err) return console.log(err);

txt = txt + '\nAppended something!';

fs.writeFile(myFile, txt, notifyUser);

var myFile = '/tmp/test';

fs.readFile(myFile, 'utf8', appendText);

Xem tiếp...

Bạn thế code trên đẹp trai hơn chưa?


Mặc dù cách viết code đã giải quyết được phần nào vấn đề. Nhưng nó vẫn chưa phải là giải pháp tốt
nhất. Nếu bạn đọc lại code mà không nhớ chính xác hàm đó làm gì, bạn sẽ phải trace lại code, mà
thường thì code của hàm đó lại trôi tuột ở đâu đó. Rất mất thời gian.

Chúng ta còn có giải pháp tốt hơn, ngay phía bên dưới thôi!

4. Sử dụng module Async.js

Đúng với tên gọi của nó, module Async.js sẽ giúp bạn xử lý các hàm bất độ theo cách đồng bộ.

Module này có rất nhiều methods để bạn chọn như series, parallel, waterfall,… Vì vậy, bạn nên dành chút
thời gian để đọc tài liệu hướng dẫn của tác giả trước khi quyết định chọn method nào.

Async.js thực sự là một thư viện tốt, nhưng nếu lạm dụng quá thì cũng không tốt. Bạn nên nhớ Nodejs là
nền tảng được thiết kế cho hệ thống xử lý bất đồng bộ, với ưu điểm xử lý realtime. Nên nếu dự án toàn
sử dụng Async.js để xử lý các tác vụ theo kiểu đồng bộ tuần tự là tự đập bỏ điểm mạnh của Nodejs.

Đây là đoạn code sử dụng Async.js cho ví dụ trên:

You might also like