Unexpected behavior in asynchronous javascript

Asked

Viewed 75 times

2

I am writing backend code using javascript, Node and npm 'mysql' and 'request' modules. I tried to write a module to make a pooling of SQL database connections by different API calls in various files of my project. My mysqlLib.js module:

var mysql = require('mysql');

var pool = mysql.createPool({
    host : settings.host_DB,
    user : settings.user_DB,
    password : settings.senha_DB,
    database : settings.DB
});

module.exports.getConnection = function(callback) {
  pool.getConnection(function(err, conn) {
    if(err) {
      return callback(err);
    }
    callback(err, conn);
    conn.release();
  });
};

When finishing this module I decided to test with a Tester.js file

var mysql = require('./lib/mysqlLib.js');
var request = require('request');

mysql.getConnection(function(err, conn) {
    conn.query(query1, function(err) {
        conn.query(query2, function(err) {
            request.get(url1, function(err, httpResponse, body){
                conn.query(query3);
            });     
        });
    });
});

In fact, the code accomplished what I wanted it to do: Every time I need to make changes to my database through some middleware in the API I wrote to any of my files, use the mysqlLib.js getConnection method to pull a connection from my pool and at the end of the use release it back into the pool. What’s bothering me is that I noticed something that should be leading this little program to an error and it’s not... You see, the function 'Conn.query(query, callback)' is asynchronous, that is to say it does not interrupt the flow of code. Thus, I thought that by performing the first invocation of 'Conn.query' in Tester.js, this function would be run asynchronously allowing the callback of getConnection to come to an end. Shouldn’t that mean the program would finish callback and release() the connection that was pulled? I thought I could call the first Conn.query but once callback reached its end and the connection was released I could not accomplish the other nested queries at first for lack of it but they are all being executed without error! I wonder what may possibly be happening, why the connection is released only after the termination of all the nested callbacks in the callback of getConnection?

  • I have little experience in Ode.js, but I’ll take a guess: it may be that function conn.release() has a check to avoid closing connections that are being used in queries, so the code stops in the release and only continues when the callback of conn.query() returns.

1 answer

1


This library allows you to set the maximum number of connections when using pool. If you do not specify a value the maximum is 10 as documented:

connectionLimit: The Maximum number of Connections to create at Once. (Default: 10)

In addition, although the code is asynchronous, the browser reads the functions synchronously. That is when it reads the first conn.query(..., it opens a link and only ends it when the function returns. Not the asynchronous return via callback, but when you have read all the code within the function. Now before that happens the mysql will not close unless there is a .end() specific in the code.

Thus, before the first function gives return he opens the nests, so the last to be called is the first to be closed.

  • Thanks for the clarification Sergio, if this happens in the browser likely to happen also on the right server?

  • @Matheusbafutto that your code is server-side, my answer is about code that runs on the server (Node.js) since Mysql is server-side

  • Yes, sorry for the misunderstanding... Do you have a reference link that explains this behavior for javascript (whether it’s a documentation section or something)? Only for future consultations.

  • 1

    @Matheusbafutto asks here if you have any more questions, you can read here http://answall.com/q/27177/129, and there are other questions with answers that help a lot too. See you soon!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.