Callback Hell Là Gì

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.

Bạn đang xem: Callback hell là gì

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ì.

*


Nội dung chính của bài viết

#6 cách xử lý callback hell trong javascript dễ nhất2. Nên đặt tên cho callback trong javascript6. Async/Await nhằm giảm khả năng xảy ra callback hell trong javascript

#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){ ... }); }); }); });});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.

#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.

Xem thêm: Làm Thế Nào Để Đi Xe Máy Vững, 10 Kỹ Năng Người Đi Xe Máy Cần Có

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.jsmodule.exports = { hello: function(name) { console.log("Hello, " + name); }, bye: function(name) { console.log("Goodbye, " + name); }};Sau đó gọi ở ứng dụng như sau:

var greeter = require("test");greeter.hello("Monkey");greeter.bye("Steven");

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!"); });});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!"); });});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?

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); Bạn thế code trên đẹp trai hơn chưa?