Lấy cảm hứng từ bài viết Năm điều bạn nên ngừng khi lập trình với jQuery của tác giả Burke Holland, hôm nay tôi sẽ thảo luận với các bạn và nêu lên 7 điều "nổi bật" bạn nên ngừng làm khi lập trình với Node.js:

  1. Ngừng sử dụng callback.
  2. Ngừng sử dụng * với các phiên bản package.
  3. Ngừng sử dụng console.log để debug.
  4. Ngừng sử dụng GET và POST với mọi thứ.
  5. Ngừng sử dụng dấu chấm phẩy (;).
  6. Ngừng sử dụng phong cách dấu-phẩy-phía-trước..
  7. Ngừng việc giới hạn kết nối với giá trị mặc định maxSockets.

 

1. Ngừng sử dụng callback

Callback và JavaScript/Node.js (tính cả các pattern lõi) được ví von như là bánh mì và bơ vậy, luôn luôn song hành cùng với nhau. Tuy nhiên, bạn nên ngừng sử dụng callback để lồng code của nhiều phương thức. Nếu không thì bạn sẽ gặp phải tình huống quen thuộc Callback Hell.

Thời buổi bây giờ mọi người đã chuyển sang dùng async hết rồi. Đặc biệt là các phương thức series() và waterfall().

Để minh họa cho sự khác biệt mạnh mẽ đó, ta hãy cùng tham khảo 1 ví dụ dưới đây. Ta sẽ thực hiện nhiều tác vụ để tìm người dùng bằng callback, sau đó tìm các bài đăng của người dùng đó:

codeA(function(a){
  codeB(function(b){
    codeC(function(c){
      codeD(function(d){
        // Final callback code        
      })
    })
  })
})

Với phương thức series():

async.series([
  function(callback){
    // code a
    callback(null, 'a')
  },
  function(callback){
    // code b
    callback(null, 'b')
  },
  function(callback){
    // code c
    callback(null, 'c')
  },
  function(callback){
    // code d
    callback(null, 'd')
  }],
  // optional callback
  function(err, results){
    // results is ['a', 'b', 'c', 'd']
    // final callback code
  }
)

Với hàm waterfall():

async.waterfall([
  function(callback){
    // code a
    callback(null, 'a', 'b')
  },
  function(arg1, arg2, callback){
    // arg1 is equals 'a' and arg2 is 'b'
    // Code c
    callback(null, 'c')
  },
  function(arg1, callback){      
    // arg1 is 'c'
    // code d
    callback(null, 'd');
  }], function (err, result) {
   // result is 'd'    
  }
)

 

2. Ngừng sử dụng * với các phiên bản package

Dấu * thay thế cho phiên bản cụ thể của package trong file package.json trông có vẻ tiện - nó sẽ tự động update. Sai lầm! Bạn nên sử dụng phiên bản cụ thể để tránh việc có bất kì package thuộc bên thứ 3 thay đổi dẫn đến lỗi ứng dụng, khiến bạn thức dậy giữa đêm và thốt lên: "Cái *** gì đã xảy ra vậy?".

Điều này càng đặc biệt đúng nếu bạn không commit thư mục node_modules hay không sử dụng shrinkwrap.

Một ví dụ "kinh điển" với file package.json HackHall vào khoảng hè 2013:

{
    "name": "hackhall",
    "version": "0.0.1",
    "private": true,
    "main": "server",
    "scripts": {
        "start": "node server"
    },
    "dependencies": {
        "express": ">=2.2.0",
        "jade": "*",
        "mongodb": "*",
        "mongoose":"",
        "oauth":"*"
    },
    "devDependencies":{
        "mocha": "",
        "superagent":""
    },
    "engines": {
      "node": ">=0.6"
    }
}

Đây lại là 1 ví dụ đáng để học tập từ cuốn sách The Practical Node.js (2014):

{
  "name": "blog-express",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node app.js",
    "test": "mocha test"
  },
  "dependencies": {
    "express": "3.4.5",
    "jade": "0.35.0",
    "mongoskin": "~0.6.1",
    "stylus": "~0.40.3",
    "mocha": "1.16.2",
    "superagent": "0.15.7",
    "expect.js": "0.2.0"
  }
}

Nếu bạn không muốn phải truy cập trang npm liên tục chỉ để kiểm tra phiên bản, bạn có thể sử dụng câu lệnh $ npm install tên_package --save để lưu phiên bản của package vào file package.json.

Nếu module đã được cài đặt bạn có thể:

  • Gõ lệnh $ npm ls.
  • Mở thư mục package và copy phiên bản package package.json.

 

3. Ngừng sử dụng console.log để debug ứng dụng Node.js

Như thế nào là 1 debugger tốt? Là console.log. Nhanh nè, không làm gián đoạn nè, cung cấp cho ta nhiều thông tin cần thiết nè (giá trị của mấy cái biến dở hơi),... Tại sao lại khuyên ngừng sử dụng nó chứ? Bởi vì 1 debugger thực thụ như Node Inspector sẽ cung cấp không chỉ giá trị của biến được hard-code mà còn cho bạn sự linh động để nhìn sâu hơn vào tiến trình.

http://m03s6dh33i0jtc3uzfml36au-wpengine.netdna-ssl.com/media/wp-content/uploads/node-inspector-watch.png

Lấy ví dụ, tôi có 1 điều kiện (biến resubmit có type là boolean) có thể hoạt động không đúng:

if (resubmit && post.published && user.plan.paid && post.isVisible) {
  // code A
} else {
 // code B
}

Với console.log tôi chỉ có thể console.log(resubmit). hay là console.lo(resubmit, .....). Tuy nhiên với debugger, tôi có thể xem được mọi thứ tôi có thể truy cập trong scope đó. Nếu vẫn chưa đủ, tôi sẽ step over hay step in để xem thêm.

 

4. Ngừng sử dụng GET và POST với mọi thứ ở Node server

Hãy ngừng sử dụng asdjasd cho mọi request HTTP. RESTful API có PUT và DELETE nên hãy sử dụng chúng cho các thao tác cập nhật và xóa. (wiki).

Lấy ví dụ với Express route, thay vì dùng POST để cập nhật 1 bản ghi, ta có thể dùng PUT:

app.post('/comments/update/:id', routes.comments.update)
app.put('/comments/:id', routes.comments.update)

Bạn có thể tìm hiểu thêm ở hướng dẫn RESTful API.

 

5. Ngừng sử dụng dấu chấm phẩy (;)

Dấu chấm phẩy hoàn toàn không bắt buộc , vì ECMAScript (1 chuẩn Node.js và trình thực thi JavaScript của trình duyệt) có 1 tính năng tự thêm dấu chấm phẩy (ASI - Automatic Semicolon Insertion). Đây là 1 bản phác thảo tài liệu ECMAScript 6 (ES6) về ASI.

Lý do chính là dấu chấm phẩy không bắt buộc, ngoại trừ 2 trường hợp: phía trước IIEF và bên trong vòng lặp FOR .

Các vấn đề khi sử dụng dấu chấm phẩy:

  • Phải gõ nhiều hơn: Với 1000 dòng code ta sẽ có thêm tầm 1000 ký tự chấm phẩy thừa thãi.
  • Không nhất quán: Khi bạn quên chấm phẩy, về cơ bản source code vẫn làm việc bình thường, nhưng sẽ dẫn đến vấn đề là code không nhất quán (bạn có thể giải quyết vấn đề bằng linting, tuy nhiên sẽ cần thêm bước cấu hình).

Một số dự án Node.js được viết theo phong cách bỏ dấu chấm phẩy:

  • NPM: trình quản lý package Node.js.
  • Request: 1 module cho phép tạo các request HTTP.

Nếu bạn vẫn còn phân vân do Doug Crockford bảo bạn rằng phải sử dụng dấu chấm phẩy? Vậy thì bạn nên đọc Một lá thư gửi đến các lãnh đạo JavaScript về dấu chấm phẩy.

 

6. Ngừng sử dụng phong cách viết dấu-phẩy-ở-trước

Mục này thì hoàn toàn là ý kiến chủ quan của tôi, nó không hẳn là quan trọng. Nhưng tôi cần phải bày tỏ sự không thích của mình với cái phong cách này.

Phong cách này đơn giản chỉ là viết dấu phẩy ở phía trước thay vì ở phía sau, giống như cái thứ ngay dưới đây:

var arr = [ 'nodejs'
  , 'python'
  , 'ruby'
  , 'php'
  , 'java'
]

thay vì cách truyền thống:

var arr = [ 'nodejs', 
  'python', 
  'ruby', 
  'php',
  'java'
]

Làm ơn đừng có học theo phong cách này. Tôi chả quan tâm rằng nó tốt như thế nào trong việc tìm kiếm dấu chấm phẩy. Phong cách viết dấu-phẩy-ở-trước này thực sự rất kì cục, bởi vì chúng tôi không bao giờ sử dụng phong cách này trong ngôn ngữ viết thông thường. Chả ai lại viết như thế này cả:

Paleo lifestyle is good for ,adult men ,adult women ,children ,and elderly people.

Theo ý kiến thiển cận của tôi, phong cách dấu-phẩy-ở-trước này thực sự khó cho não bộ tiếp thu và khá là ngớ ngẩn.

 

7. Ngừng việc giới hạn kết nối với giá trị mặc định maxSockets

Giá trị mặc định của maxSockets là 5 và nó xác định giới hạn số lượng socket trên 1 host (tài liệu).

Để tránh hệ thống gặp tình trạng nghẽn cổ chai, hãy làm như sau:

var http = require('http')
http.globalAgent.maxSockets = 10

Hoặc nếu bạn muốn nó không giới hạn:

require('http').globalAgent.maxSockets = Infinity

Đây là 1 bài viết so sánh khá tốt về vấn đề này.

Một phương án khác đó là tắt hết pooling (agent: false) giống như LinkIn hay Substack.

 

Bài viết được dịch từ: https://webapplog.com/seven-things-you-should-stop-doing-with-node-js/