javascript promises for pooling connections and ex

2019-09-03 14:54发布

问题:

I'm wondering if this approach is correct or does it need further refinements, maybe promisify custom mySQL getConnection method as well???

    request: function(queryRequest) {
        return new Promise(function(resolve, reject){
            Database.getConnection(function(error, connection){
                if(error) {
                    reject({error: error, queryRequest: queryRequest});
                } else {
                    connection.query(queryRequest.sql, queryRequest.values, function(error, rows, fields){
                        if(error) {
                            reject({error: error, queryRequest: queryRequest});
                        } else {
                            resolve({rows: rows, fields: fields, queryRequest: queryRequest});
                        }
                    });
                }
            });
        });
    },

The getConnection method defined in Database module.

    getConnection: function(callback) {
        this.pool.getConnection(function(error, connection){
            callback(error, connection);
        });
    },

回答1:

maybe promisify custom mySQL getConnection method as well?

Only maybe. While it could be considered a bit cleaner, and makes your callback pyramid a bit flatter, it doesn't improve the code much:

function request(queryRequest) {
    return new Promise(function(resolve, reject) {
        Database.getConnection(function(error, connection) {
            if (error)
                reject(error);
            else
                resolve(connection);
        });
    }).then(function(connection) {
        var res = new Promise(function(resolve, reject) {
            connection.query(queryRequest.sql, queryRequest.values, function(error, rows, fields) {
                if (error)
                    reject(error);
                else
                    resolve({rows: rows, fields: fields, queryRequest: queryRequest});
            });
        });
        return res;
    }).catch(function(error) {
        throw {error: error, queryRequest: queryRequest};
    });
}

I'm wondering if this approach is correct

For database connections, you might want to have a look at the disposer pattern. If you don't need it, you still should remember to always release your connections, using something like

….then(function (connection) {
    var res = …;
    // better be solved using `finally` where supported
    return res.then(end, end);
    function end() {
        connection.release();
        return res;
    }
})

Also, rejecting promises with objects that are no Errors is a bad practise, you might better do

….catch(function(error) {
    error.queryRequest = queryRequest;
    throw error;
})

or the equivalent in your original pattern.