Hỏi về mysql với nodejs



  • e có đoạn code này.

            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ì k có giá trị, vậy e phải làm sao để gán giá trị rows[0].img cho biến kidshy ạ?



  • kidshy = rows[0].img, bằng rồi này.
    Cái này chả liên quan đến mysql đâu bạn, tìm trong forum mấy topic asynchronous javascript mà nghiên cứu thêm.



  • Nó chỉ có tác dụng trong hàm thôi bạn, ra khỏi truy vấn thì nó về giá trị ban đầu



  • Do hàm connection.query là một hàm không đồng bộ (async function) nên hàm console.log được thực thi trước khi biến kidshy được gán bằng rows[0].img.
    Bạn có thể kiểm tra thứ tự thực thi như sau:

    connection.query('SELECT * from kidshy WHERE id = 1', function(err, rows, fields) {
        console.log(1);
    });
    console.log(2);
    

    Bạn sẽ dễ dàng thấy giá trị 2 được in ra màn hình trước giá trị 1. Thứ tự thực thi cũng là khái niệm căn bản nhất mà bạn cần nắm được khi tiến hành lập trình không đồng bộ (asynchronous programming).

    Để nhận được giá trị mới của biến kidshy, bạn phải đợi đến khi hàm connection.query được thực thi xong bằng cách đưa hàm console.log đặt trong callback của hàm connection.query.

    var kidshy;
    connection.query('SELECT * from kidshy WHERE id = 1', function(err, rows, fields) {
        //Luôn luôn xử lý lỗi (handle error) trước tiên.
        if(err){
            return cb(err);
        }
        kidshy = rows[0].img;
        console.log(kidshy);
    });
    


  • @tresdin đã nói:

    connection.query

    bạn vẫn console.log trong hàm connection.query. bạn thử dùng console.log(kidshy) ngoài hàm connection.query sẽ thấy lỗi



  • @Một-Thằng-Điên đã nói:

    Giá trị kidshy chỉ bị thay đổi trong hàm truy vấn đó, ra đến console log thì k có giá trị, vậy e phải làm sao để gán giá trị rows[0].img cho biến kidshy ạ?

    Mấy bác nói đây là vấn đề của bất đồng bộ (asynchronous) là đúng đấy.

    Thực ra là giá trị kidshy vẫn bị thay đổi nhưng vấn đề của chủ thread 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

    • . ^
    0


  • Vậy cách xử lý là gì vậy ạ



  • Cách xử lý là :

    • Tìm hiểu trước khi hỏi
    • Ôn lại kiến thức
    • Đọc comments của mọi người, nếu k hiểu ở đâu thì hỏi chứ đừng lên mạng để bắt người khác giải quyết vấn đề của mình.
      Mình nghĩ đó là mindset cần có của 1 developer.


  • This post is deleted!


  • @Một-Thằng-Điên đã nói:

    Vậy cách xử lý là gì vậy ạ

    var p = new Promise(function(resolve, reject) {
    connection.query('SELECT * from kidshy WHERE id = 1', function(err, rows, fields) {
    resolve(rows[0].img);
    });
    });
    p.then(function(val) {
    console.log(val);
    })



  • Anh có thể đọc qua bài viết này http://nodejs.vn/topic/15/promise-async-thì-sao-nào. Sau đó dùng thư viện bluebird để implement nha.


Log in to reply