2

Just started to learn express js framework ,here is my simple database query execution part its invoked with this url localhost:3000/api/test.

db.query('SELECT * FROM user', function (error, results, fields) {
            if (error) throw error;
            console.log('The result is:', results[0].id);

            return results;
        });

Does it really asynchronous?? suppose another user request this url does he need to wait for the previous query execution??.

I've heard about async package ,but don't know how this is applicable in my case

UPDATE

I got proper result in console.log(); but when i return the result i got undefined error

Here is my model.js

module.exports = {
    getUser:function () {
        db.query('SELECT * FROM user', function (error, results, fields) {
            if (error) throw error;
            console.log('The result is: ', results[0].id);

        });

    }

}

From my controller.js

var model = require('../models/user.js');
module.exports = {
    getData : function(req, res){
        //invoke model
        console.log(model.getUser());

    }
}
Jabaa
  • 1,743
  • 7
  • 31
  • 60
  • Possible duplicate of [What is the difference between synchronous and asynchronous programming (in node.js)](http://stackoverflow.com/questions/16336367/what-is-the-difference-between-synchronous-and-asynchronous-programming-in-node) – Erazihel Mar 31 '17 at 10:05

2 Answers2

3

Node is non-blocking and will serve this request as and when it's called.

If another user hits this endpoint then it will execute again regardless if the first query has completed or not (unless the SQL has locked the table, in which case all consecutive connections/queries will wait and may timeout because of it). This happens on a connection basis.

You should make sure to check your SQL server (MySQL?) configs here to make sure there are enough max_connections to be able to cope with whatever load you are expecting.

Remember that the biggest bottleneck to an application is usually the database.


Your query above will need a callback to return the data asynchronously.

db.query('SELECT * FROM user', function (error, results, fields) {
    if (error) throw error;
    console.log('The result is:', results[0].id);

    //cb=callback function passed in to context
    if (cb) cb(results);
});

Updated answer from updated question

In your model.js:

module.exports = {
    getUser:function (cb) {
        db.query('SELECT * FROM user', function (error, results, fields) {
            if (error) throw error;
            console.log('The result is: ', results[0].id);
            if (cb) cb(results);

        });

    }

}

In your controller.js:

module.exports = {
    getData : function(req, res){
        //invoke model

        model.getUser(function(results) {
            console.log(results);
        });

    }
}
AO_
  • 2,573
  • 3
  • 30
  • 31
  • so when another request is coming it will handle simultaneously?? – Jabaa Mar 31 '17 at 10:20
  • One more question do i need a callback function to handle the result?? – Jabaa Mar 31 '17 at 10:22
  • @Jabaa: Yes, it is simultaneous and you don't need to do any callbacks. – AO_ Mar 31 '17 at 10:30
  • But when i return the results i got undefined – Jabaa Mar 31 '17 at 10:31
  • @Jabaa: Have you tried seeing if anything comes back? `console.log(results);` . Is the database connection active when you place this call? – AO_ Mar 31 '17 at 10:33
  • console.log(results); gives output but when i return those result `return results` i got undefined error – Jabaa Mar 31 '17 at 10:35
  • @Jabaa: Using `return` here uses a different scope context, so essentially the function returns as undefined automatically, you will need to use a callback here. I have updated my answer to illustrate this. – AO_ Mar 31 '17 at 10:40
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/139570/discussion-between-jabaa-and-0x616f). – Jabaa Mar 31 '17 at 10:41
0

When you deal with callback, the safe and clean way to handle them is Promises. It's now standard in JavaScript and don't require any module.

And yes it is asynchronous. Behind, there'll be network access and dialogs with the database server. Only when they're done chatting will the callback be called.

module.exports = {
    getUser: function () {
        // wrap asynchronously called callback in Promise
        new Promise((resolve, reject) => {
            db.query("SELECT * FROM user", (error, results, fields) => {
                if (error) {
                    reject(error); // similar to "throw"
                }
                else {
                    resolve({ results, fields }); // similar to "return"
                }
            });
        });
    }
};

How do you use it:

Vanilla notation:

// similar to "try"
model.getUser()
.then((answer) => {
    console.log("answer", answer);
})
// similar to "catch"
.catch((error) => {
    console.log("error", error);
});

async-await notation (only available in last versions of nodejs & browsers):

// you must be in an async environement to use "await"
async function wrapper() {
    try {
        var answer = await model.getUser(); // wait for Promise resolution
        console.log("answer", answer);
    }
    catch(error) {
        console.log("error", error);
    }
}
// async function return automatically a Promise so you can chain them easily
wrapper();
Kulvar
  • 1,139
  • 9
  • 22