10 lỗi mà các dev NodeJS thường mắc phải (phần 2)

95

PHẦN 1

Lỗi #4: Mong muốn các callbacks chạy đồng bộ

Lập trình không đồng bộ (async) với các callbacks có thể không có gì đặc biệt với JavaScript và Node.js, nhưng chúng là lý do dẫn đến sự nổi tiếng của ngôn ngữ này. Với các ngôn ngữ lập trình khác, chúng ta đã quen với việc dự đoán được thứ tự execution khi 2 lệnh thực hiện lần lượt, nếu không có instruction đặc biệt chen vào giữa các câu lệnh. Khi đó, các câu lệnh điều kiện, các câu lệnh loop và các yêu cầu hàm sẽ bị giới hạn.

Tuy nhiên, trong JavaScript, với các callbacks, 1 hàm cụ thể có thể sẽ chạy không tốt nếu task đang đợi chưa được hoàn thành. Execution của hàm hiện tại sẽ chạy cho đến khi kết thúc mà không bị ngừng lại:

Lưu ý, gọi hàm “testTimeout” đầu tiên sẽ print “Begin”, sau đó print “Waiting..” cùng với tin nhắn “Done!” sau đó 1 giây.

Sau khi 1 callback đã bị loại bỏ, bạn cần phải gọi từ trong nó để thực hiện 1 hành động khác.

Lỗi #5: Chỉ định “exports”, thay vì “module.exports”

Trong Node.js, mỗi file là 1 module nhỏ và độc lập. Nếu package của bạn có 2 files, thì có thể “a.js” và “b.js”, sau đó để “b.js” tiếp cận các functions “a.js”’s, “a.js” phải xuất nó ra bằng cách thêm các properties đến đối tượng xuất:

Sau khi thực hiện xong, bất kì dev nào muốn gọi “a.js” sẽ được nhận 1 đối tượng với hàm property “verifyPassword”:

Tuy nhiên, sẽ ra sao nếu bạn muốn xuất trực tiếp hàm này,và không phải là property của đối tượng khác? Chúng ta có thể ghi đè lên các exports để làm việc này, nhưng chúng ta không nên xem nó là global variable:

Lưu ý cách thức chúng ta đang xem “exports” là 1 property của đối tượng module. Sự khác biệt ở đây, giữa “module.exports” và “exports” là rất quan trọng. Đây cũng thường là nguyên nhân khiến các lập trình viên Node.js mới bực bội, khó chịu.

Lỗi #6: Bỏ các lỗi từ Callbacks bên trong

JavaScript là khái niệm của các exceptions. Sự giống nhau về syntax của hầu hết tất cả các ngôn ngữ truyền thống với hỗ trợ xử lý exceptions, như Java và C++, JavaScript có thể “ném” (throws) và bắt (catch) các exceptions trong các khối try-catch:

Tuy nhiên, try-catch sẽ không hoạt động như bạn muốn trong các tình huống không đồng bộ. Ví dụ, nếu bạn muốn bảo vệ 1 đoạn code với rất nhiều hoạt động không đồng bộ bằng 1 khối try-catch lớn, thì nó sẽ không có tác dụng nhiều:

Nếu callback đến “db.User.get” bị loại không đồng bộ thì scope chứa khối try-catch sẽ không còn phù hợp để call vẫn có thể bắt các lỗi từ trong callback.

Đây là cách giải quyết các lỗi khác nhau trong Node.js, đóng vai trò quan trọng để theo dõi pattern (err, …) trên tất cả các đối số hàm callback – đối số đầu tiên của các callbacks xuất hiện nhiều khả năng sẽ bị lỗi.

Lỗi #7: Giả thuyết Number là Integer Datatype (dữ liệu kiểu số tự nhiên)

Numbers trong JavaScript là các floating points – không có dữ liệu kiểu số tự nhiên. Vì bạn sẽ không thường gặp phải các numbers đủ lớn để gây áp lực đến các limits của float nên có thể bạn sẽ không thấy đây là vấn đề. Đó chính là thời điểm những lỗi liên quan xảy ra. Vì các floating point numbers (số thực dấu phấy động) chỉ có thể giữ các integer representations (phép kiểu số tự nhiên) ở 1 giá trị nào đó, nên nếu vươt quá giá trị đó trong bất kì phép tính nào cũng sẽ khiến giá trị đó trở nên lộn xộn. Tuy có vẻ kì lạ, nhưng dòng code dưới đây đã được xác định là đúng trong Node.js:

Thật không may, những điểm mập mờ về number trong JavaScript vẫn chưa kết thúc tại đây. Dù các Numbers là những floating points (đại số dấu phẩy động), các operators chạy trong integer data types (kiểu dữ liệu số tự nhiên) cũng chạy ở đây:

Tuy nhiên, khác với các toán tử số học, bitwise operators (phép toán thao tác bit) và shift operators (các phép toán shift) chỉ chạy trong đuôi 32 bít của các number “integer” lớn. Ví dụ, cố gắng shift “Math.pow(2, 53)” bằng 1 sẽ luôn xác định bằng 0. Cố gắng thực hiện thao tác bit 1 với number cùng độ lớn sẽ xác định bằng 1.

Có thể bạn hiếm khi phải giải quyết các numbers lớn, nhưng nếu bạn phải giải quyết chúng, sẽ có rất nhiều thư viện integer lớn hỗ trợ thực hiện các thao tác số học quan trọng trên các numbers có độ chính xác lớn, như node-bigint.

Nguồn: toptal.com via IDE Academy lược dịch (còn tiếp)