Async Mysql trong NodeJS



  • Mình viết 1 hàm find() để trả về kết quả của 1 câu truy vấn MySQL. Hiện tại đang vấp phải vấn đề là câu truy vấn bị đẩy xuống thực hiện sau cùng, hay có nghĩa là hàm find() return khi mà câu truy vấn chưa thực hiện xong.

    function find() {
        var results = [];
        mysqlConnect.query(
            query,
            function (err, rows, fields) {
                if( err ) {
                    throw err;
                }
                results = rows;
                console.log('Dòng này đáng lẽ hiện ra đầu tiên nhưng lại cuối cùng.'); 
            }
        );
        console.log('Dòng này đáng lẽ hiện ra sau nhưng lại hiện ra đầu tiên.');
        return results;
    }
    

    Bây giờ mình muốn NodeJS nó xử lý theo đúng tuần tự, mình có thử cái promise và async rồi nhưng mà nó cũng chỉ các tác dụng với các câu lệnh xử lý, còn câu truy vấn mysql thì vẫn bị xử lý cuối cùng. Ai có kinh nghiệm về vấn đề này có thể hướng dẫn mình mới. Tks !


  • Global Moderator

    @ThanhNT Mình format lại đoạn code của bạn trông dễ nhìn

    Tech-nông
    Twitter: @nhubaovu
    Profile: about.me/vunb

    0


  • đã nói trong Async Mysql trong NodeJS:

    console.log('Dòng này đáng lẽ hiện ra sau nhưng lại hiện ra đầu tiên.');

    Bạn ghi như thế này thì chứng tỏ bạn chưa hiểu về Javascript rồi, hãy nghiên cứu thêm về async trong javascript đi.



  • Mình hay dùng async với các loại database- bạn nói async chỉ tác dụng với câu xử lý là không đúng. Mã của bạn viết lại sẽ như sau :

    function find() {
      var results = [];
      async.waterfall([
    
        function(callback) {
          mysqlConnect.query(
            query,
            function(err, rows, fields) {
              if (err) {
               return callback(err, null);
              }
              results = rows;
              console.log('Dòng này đáng lẽ hiện ra đầu tiên nhưng lại cuối cùng.');
              callback(null, results);
            }
          );
        }
      ], function(err, results) {
        if (err) return err;
        console.log('Dòng này đáng lẽ hiện ra sau nhưng lại hiện ra đầu tiên.');
    /// to do something with results 
        return results;
      });
    
    }
    


  • Ha ha!
    Có gì lạ đâu. Vì đặc trưng của Nodejs là thực hiện Async. Trong câu lệnh của bạn
    mysqlConnect.query(

    )
    console.log('Dòng này đáng lẽ hiện ra sau nhưng lại hiện ra đầu tiên.');
    return results;

    Thì đương nhiên nó sẽ return lại trước khi có kết qua. Lý do là khi node yêu cầu truy vấn data, nó sẽ nói "truy vấn database nhé (nó sẽ được return khi callback thực hiện xong), tôi làm tiếp câu lệnh tiếp đây" Như vậy có nghĩa là nó sẽ thực hiện gần như đồng thời hai lệnh return và query. Và bạn sẽ được return trước khi database hoàn thành. Muốn return được kết quả bạn phải để return trong function callback của hàm query.



  • @hidemanvn Tks bạn ! Nhưng mình có làm như bạn nói nhưng kết quả vẫn thế :

    var results = [];
        async.waterfall(
            [
                function(callback) {
                    AppModel.prototype.mysqlConnect.query(
                        query,
                        function (err, rows, fields) {
                            if( err ) {
                                throw err;
                            }
                            results = rows;
                            console.log('------1: ', rows);
                            callback(null, results);
                        }
                    );
                }
            ],
            function(err, result) {
                if (err) return err;
                console.log('------2: ', result);
                return result;
            }
        );
        console.log('------3: ', results);
    

    Khi mình chạy thì kết quả in ra màn hình là :

    ------3:  []
    Kết quả ở lời gọi hàm:  undefined 
    ------1:  [ RowDataPacket { id: 1, name: 'name1' }]
    ------2:  [ RowDataPacket { id: 1, name: 'name1' }]
    

    @flyare Việc mình return trong callback của async.waterfall hay của hàm truy vấn query đều ko có tác dụng



  • @ThanhNT Bạn phải sử dụng console.log('------3: ', results); ngay sau hàm trả về result hoặc ít ra gắn nó vào hàm callback

    var aCall = function(){
     console.log('------4: ', results); 
    }
    .....
     async.waterfall(
    ....
    function(err, result) {
                if (err) return err;
                console.log('------2: ', result);
                // các đoạn code phía sau ở đây hoặc dùng callback gọi
                console.log('------3: ', results); 
                aCall();
            }
        );
    

Log in to reply