Bài 6 nodejs: I/O non-Blocking: vài linh kiện nho nhỏ

Bài 6 nodejs: I/O non-Blocking: vài linh kiện nho nhỏ

Trong bài này mình giới thiệu hai đoạn mã nhỏ cũng khá lý thú để những post sau này mình sẽ dùng cho những thí dụ về I/O non-Blocking. Đoạn mã đầu tiên là một hàm nhỏ ghi lại thời điểm hiện tại đi cùng với đoạn text. Hàm này tiện dụng cho logging. Mình đặt tên file này là linhkien.js nhé.

function now(txt) {
    console.log(new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '')+' '+txt);
}
now('> Hello World');

Khi chạy nó sẽ ra như thế này, cũng vui vui. Các bạn tự nghiệm hàm chạy làm sao nhé.

C:\nodeDev> node linhkien.js
2014-05-11 23:05:05 > Hello World
C:\nodeDev>

Hàm thứ hai là hàm wait. Hàm này chẳng làm gì cả chỉ looping around doing nothing cho một thời gian x mili giây đồng hồ nào đó. Hàm có tính cách blocking, có nghĩa khi hàm này chạy thì không có cái gì chạy cả mà phải chờ đến khi hàm này chạy xong. Các bạn nhớ không? Single thread á. Again, bạn tự nghiệm nhé.

function wait(miliSeconds) {
    var startTime = new Date().getTime();
    while (new Date().getTime() < startTime + miliSeconds);
}

 

Bạn hợp hai hàm này vào cùng 1 file như sau:

function now(txt) {
    console.log(new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '')+' '+txt);
}

function wait(miliSeconds) {
    var startTime = new Date().getTime();
    while (new Date().getTime() < startTime + miliSeconds);
}

now('> Start to wait');
wait(5000);
now('> Finish waiting');

 

Khi chạy nó sẽ ra như thế này, cũng vui vui. Các bạn tự nghiệm hàm chạy làm sao nhé. Để ý mốc thời gian cách nhau 5 giây.

%(blue)[C:\nodeDev> node linhkien.js
2014-05-11 23:05:17 > Start to wait
2014-05-11 23:05:22 > Finish waiting
C:\nodeDev>]

I/O non-Blocking: setTimeout

Trước khi đề cập đến setTimeout, mình chỉnh sửa hàm wait của mình chút đỉnh để dễ so sách nha. Cũng không gì nhiều, chỉ chêm vào một parameter. Parameter này là một hàm mình muốn chạy sau khi thời gian wait chấm dứt. Hàm gọi hàm mà mình đã đề cập ở post trước áh. Trong trường hợp này, hàm mình muốn chạy chỉ đơn giản là now với dòng chữ End of waiting. Nhìn đoạn mã bạn sẽ hiểu ngay.

function now(txt) {
    console.log(new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '')+' '+txt);
}

function wait(fn, miliSeconds) {
    var startTime = new Date().getTime();
    while (new Date().getTime() < startTime + miliSeconds);
    fn();
}

now('> Start to wait');
wait(function(){now('> End of waiting');}, 5000);

 

Khi chạy nó sẽ ra như thế này, cũng vui vui. Để ý đến mốc giờ, start và end cách nhau 5 giây (hay là 5000 mili giây). Các bạn tự nghiệm hàm chạy làm sao nhé.

 > C:\nodeDev> node linhkien.js
2014-05-11 23:05:17 > Start to wait
2014-05-11 23:05:22 > End of waiting
C:\nodeDev>

Bây giờ thì đến setTimeout. Hàm này trong core của Node.js. Về hình thức hàm này y chang như hàm wait, implementation thì lại khác. Trong khi wait is blocking, setTimeout lại là non-Blocking. Đầu tiên ta xem hai hàm này giống chỗ nào nha. Từ đoạn mã trên ta chỉ thay thế tên hàm wait với setTimeout (hàng cuối) và run. Kết quả cũng sẽ giống nhau.

function now(txt) {
    console.log(new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '')+' '+txt);
}

function wait(fn, miliSeconds) {
    var startTime = new Date().getTime();
    while (new Date().getTime() < startTime + miliSeconds);
    fn();
}

now('> Start to wait');
setTimeout(function(){now('> End of waiting');}, 5000); // Thay wait bằng setTimeout

Khi chạy nó sẽ ra như thế này. Để ý đến mốc giờ, start và end cách nhau 5 giây (hay là 5000 mili giây) như trên.

 > C:\nodeDev> node linhkien.js
2014-05-11 23:12:11 > Start to wait
2014-05-11 23:12:16 > End of waiting
C:\nodeDev>

Để thấy sự khác biệt giữ wait (blocking) và setTimeout (non-Blocking) mình chỉ việc kèm thêm một hành động nào đó ngay sau cùng và quan sát xem khi nào thì hành động này được run. Theo định nghĩa, với blocking, hành động cuối sẽ chạy sau khi thời gian wait chấm dứt. Ngược lại, với non-Blocking, hành động cuối sẽ bắt đầu ngay sau khi bắt đầu waiting. Mình sẽ thử cả hai để so sánh nha.

  • Thêm vào cuối đoạn mã now('> Start to do something else');
  • Hai đoạn mã dưới đây mình không hiển thị mã của 2 hàm now và wait cho dễ nhìn.
now('> Start to wait');
wait(function(){now('> End of waiting');}, 5000); 
now('> Start to do something else');

 > C:\nodeDev> node linhkien.js
2014-05-11 23:22:10 > Start to wait
2014-05-11 23:22:15 > End of waiting
2014-05-11 23:22:15 > Start to do something else
C:\nodeDev>

now('> Start to wait');
setTimeout(function(){now('> End of waiting');}, 5000); 
now('> Start to do something else');

 > C:\nodeDev> node linhkien.js
2014-05-11 23:23:20 > Start to wait
2014-05-11 23:23:20 > Start to do something else
2014-05-11 23:23:25 > End of waiting
C:\nodeDev>

Tóm tắt

  • Post này trình bày sự khác biệt giữa blocking và non-Blocking operation với mục đích nhấn mạnh non-Blockinghành xử thế nào. Thông hiểu khái niệm non-Blocking sẽ giúp chúng ta lập trình dễ dàng hơn với node.js.
  • Một điểm khác mình cũng muốn đề cập là callback. Cái hàm được gọi bởi hàm setTimeout là một callback function. Chung chung có thể hiểu như là, sau khi hết hạn timeout thì anh gọi cho tôi biết để tôi bắt đầu làm việc của tôi. Trong ví dụ này hết hạn timeout là event. Những events khác, thường là IO, có thể như file opened, file close, end of file, database connected, end of search, vân vân.

I/O non-Blocking: process.nextTick

Các posts trước mình đã viết hàm wait, hàm chẳng làm gì cả chỉ loop around và ngăn trở khởi động các hàm khác. Hàm không có giá trị thực tiễn, chỉ được dùng để dẫn nhập vào khái niệm non-Blocking & single-threaded, khái niệm quan trọng nhất của node.js. Mình đã đề cập đến hàm setTimeout để quan sát tương đồng và tương dị với hàm wait. setTimeout căn bản là một loại hàm non-Blocking dùng để hoãn lại một hoạt động nào đó đồng thời cứ để những hoạt động khác có xếp hàng trong thread (event queue) diễn tiến như thường lệ. Hàm setTimeout có 2 parameters. Parameter thứ nhất là một hàm mình muốn hoãn, parameter thứ hai là khoản thời gian hõan tính theo mili giây. Điều này dẫn đến câu hỏi: Nếu thời gian hõan là 0 mili giây thì sao nhỉ? Good question. Nếu thời gian hoãn là 0 thì hoạt động hoãn sẽ được đặt ngay cuối event queue. Có nghĩa ngay tại thời điểm setTimeout được gọi, hàm callback là event cuối cùng. Quan sát đoạn mã sau đây bạn sẽ thấy.

function now(txt) {
    console.log(new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '')+' '+txt);
}

now('> Start to wait');
setTimeout(function(){now('> End of waiting');}, 0); 
now('> Start to do something else');

Khi chạy nó sẽ ra như thế này. Để ý đến mốc giờ, start và end giống nhau, chỉ là thứ tự trên dưới. Nên nhớ là giờ hiển thị ở đây là giây chứ không phải mili giây.

 > C:\nodeDev> node linhkien.js
2014-05-14 08:12:11 > Start to wait
2014-05-14 08:12:11 > Start to do something else
2014-05-14 08:12:11 > End of waiting
C:\nodeDev>

- process.nextTick

Trong core của node.js có hàm process.nextTick phản ảnh y chang như setTimeout(callback, 0). process.nextTick chỉ có 1 parameter là hàm callback, bởi lẽ process.nextTick sẽ đặt callback vào cuối event queue và parameter không cần thiết. Bạn thực tập đoạn mã dưới và ngiệm sét nhé.

 

now('> Start to wait');
process.nextTick(function(){now('> End of waiting');}); 
now('> Start to do something else');

 > C:\nodeDev> node linhkien.js
2014-05-14 08:12:18 > Start to wait
2014-05-14 08:12:18 > Start to do something else
2014-05-14 08:12:18 > End of waiting
C:\nodeDev>

- Tóm tắt

Ứng dụng của setTimeout và process.nextTick để viết mã non-Blocking trong lập trình node.js. Điều này dẫn đến câu hỏi: Nếu đã có setTimeout(callback, 0) thì việc gì phải làm thêm process.nextTick(callback)? Có phải là rắc rối tơ? Thật sư hai hàm có hai ứng dụng khác nhau, trong điều kiện thời gian hoãn là 0, hàm process.nextTick hữu hiệu hơn setTimeout rất nhiều. Mục đích của node.js là nhanh gọn lẹ, đó là lý do cho sự hiện hữu của process.nextTick. Mình sẽ khảo sát kỹ về cách viết và những ứng dụng trong tương lai khi có cơ hội. Ở thời điểm bắt đầu này mình lập lại lần nữanon-Blocking & single threaded là điểm đặc trưng của node.js.

  • Event queue: Trong một môi trường vi tính, nhiều sự kiện được sắp xếp theo thứ tự trước sau. Google dịch là hàng đợi sự kiện.
  • Single threaded: [Một môi trường vi tính,] sự kiện được xử lý theo chỉ một event queue.
  • non-Blocking: Một kiểu xử lý mà sự kiện đang xảy ra không dành độc quyền hiện hữu.
  • Asynchronous: (với hai hoặc nhiều vật thể hay biến cố) không cùng hiện hữu hay xảy ra trong cùng một thời gian. Suy ra, nếu không cùng một thời gian điều này đồng nghĩa với "chung chung là mọi biến có đều phải theo một thứ tự trước sau".
  • setTimeout: Một hàm trong core của node.js. Hàm này trì trệ hàm callback trong khoảng thời gian x mili giây.
  • process.nextTick: Một hàm trong core của node.js. Hàm này đặt hàm callback vào cuối event queue.
Bạn thấy bài viết này như thế nào?: 
No votes yet
Ảnh của Tommy Tran

Tommy owner Express Magazine

Drupal Developer having 9+ year experience, implementation and having strong knowledge of technical specifications, workflow development. Ability to perform effectively and efficiently in team and individually. Always enthusiastic and interseted to study new technologies

  • Skype ID: tthanhthuy

Tìm kiếm bất động sản

 

Advertisement

 

jobsora

Dich vu khu trung tphcm

Dich vu diet chuot tphcm

Dich vu diet con trung

Quảng Cáo Bài Viết

 
9 lý do máy tính bảng Android sẽ thất bại

9 lý do máy tính bảng Android sẽ thất bại

Bảo mật kém, thiếu đổi mới, doanh số thấp, Google tỏ thái độ thờ ơ, sự thách thức của iPad và Windows 8.. nhiều lý do đang cản trở thành công của tablet Android.

Setup Xdebug, Acquia Dev Desktop, and Netbeans in Windows 7

Cấu hình Xdebug, Acquia Dev Desktop, và Netbeans trên Windows 7

I usually use linux, but for various reasons I've needed to use windows lately and so I figured I would setup Xdebug, Acquia Dev Desktop, and Netbeans in Windows.

Đợt giảm giá thứ hai trong tháng của một số smartphone năm 2013

Đợt giảm giá thứ hai trong tháng của một số smartphone năm 2013

Đây là đợt giảm giá thứ hai chỉ trong vòng một tháng nay, tập trung nhiều vào các model tầm trung từ 4-6 triệu đồng.

Công ty diệt chuột T&C

 

Diet con trung