Thứ Hai, 24 tháng 4, 2017

Vấn đề bất đồng bộ trong NodeJS

Mình có đoạn code như sau:
var kidshy;
connection.query('SELECT * from kidshy WHERE id = 1', function(err, rows, fields) {
    kidshy = rows[0].img;
});
console.log(kidshy);
Giá trị kidshy chỉ bị thay đổi trong hàm truy vấn đó, ra đến console log thì không có giá trị. Tại sao vậy? Why??????????????????
Nếu bạn chưa biết nguyên nhân tại sao thì mình nghĩ các bạn cần đến cái link nè: Asynchronous programming in Node.js
Vấn đề bất đồng bộ trong NodeJS
Vấn đề bất đồng bộ trong NodeJS
Vâng lý do đã khiến cho biến kidshy không nhân được giá trị chính là do cơ chế xử lý code bất đồng bộ trong JavaScript. Chúng ta cùng đi tìm hiểu kỹ hơn về nó nhé. Thực ra là giá trị kidshy vẫn bị thay đổi nhưng vấn đề là thế này (mình mô tả như việc bạn đi mua phở):
var kidshy; // 1. Đem cặp lồng đến cửa hàng phở;
connection.query('SELECT * from kidshy WHERE id = 1'   // 2. Hô to, người đẹp làm cho anh tô phở
    // 3. Công việc của người đẹp sau khi làm phở xong
    , function(err, rows, fields) {
          // 4. Bỏ phở vào cặp lồng
          kidshy = rows[0].img;
          // 5. Xem trong cặp lồng có phở chưa (lần 1)
          console.log("lần 1:" + kidshy);
    }
);
// 6. Xem trong cặp lồng có phở chưa (lần 2)
console.log("lần 2: " + kidshy); 

/** Output
 * lần 2: undefined
 * lần 1: phở nóng hổi
 */

Với kĩ thuật xử lý của các ngôn ngữ trước đây đa số là xử lý đồng bộ (Synchronous). Luồng công việc trong hàm được xử lý tuần tự, xong việc này mới làm tới việc kia. Tức là các bước từ 1 đến 6 được thực hiện tuần tự. Với cách xử lý này thì ở bước 6 chắc chắn bạn sẽ thấy phở trong cặp lồng.
Ở đây ta gặp khái niệm bất đồng bộ (Asynchonous) (là đặc sản của NodeJS). Với kĩ thuật này thì ở bước 2, sau khi bạn gọi một suất phở, bạn không chờ người đẹp làm xong, mà sẽ lập tức nhảy qua bước 6. Ngó ngay vào cặp lồng xem có phở chưa. Và rõ ràng việc làm phở mất một khoảng thời gian nhất định. Kết quả ở bước 6 bạn sẽ thấy cặp lồng vẫn trống không.
Nếu chạy đoạn code trên bạn sẽ thấy bước 6 sẽ được thực hiện trước bước 5.
Previous Post
Next Post

post written by:

0 nhận xét: