How to promisify a MySql function using bluebird?

2019-03-30 20:36发布

问题:

Some time ago I decided to switch from PHP to node. In my first projects I didn't want to use any ORM since I thought that I didn't need to complicate my life so much learning another thing (at the moment I was learning node and angular) therefor I decided to use mysql package without anything else. It is important to say that I have some complex queries and I didn't want to learn from sctratch how to make them work using one of the 9000 ORM node have, This is what I've been doing so far:

thing.service.js

Thing.list = function (done) {
  db.query("SELECT * FROM thing...",function (err,data) {
    if (err) {
      done(err)
    } else {
      done(null,data);
    }
  });
};
module.exports = Thing;

thing.controler.js

Thing = require('thing.service.js');
Thing.list(function (err,data) {
  if (err) {
    res.status(500).send('Error D:');
  } else {
    res.json(data);
  }
});

how can I promisify this kind of functions using bluebird ? I've already tried but .... here I am asking for help. This is what I tried

var Thing = Promise.promisifyAll(require('./models/thing.service.js'));

Thing.list().then(function(){})

回答1:

I have done this way and it is working fine.

const connection = mysql.createConnection({.....});
global.db  = Bluebird.promisifyAll(connection);
db.queryAsync("SELECT * FROM users").then(function(rows){   
console.log(rows);});


回答2:

I have never had much luck with promisifyAll and IMO I prefer to handle my internal checks manually. Here is an example of how I would approach this:

//ThingModule
var Promises = require('bluebird');

Things.list = function(params) {
 return new Promises(function(resolve, reject) {
   db.query('SELECT * FROM thing...', function(err, data) {
     return (err ? reject(err) : resolve(data));
   });

 });
}

//usage
var thinger = require('ThingModule');

thinger.list().then(function(data) {
   //do something with data
})
.error(function(err) {
  console.error(err);
})


回答3:

You can also create a function that fires SQL like this :-

function sqlGun(query, obj, callback) {
    mySQLconnection.query(query, obj, function(err, rows, fields) {
        if (err) {
            console.log('Error  ==>', err);
            // throw err;
            return (err, null);
        }
        console.log(query)
        if (rows.length) {
            return callback(null, rows);
        } else {
            return callback(null, [])
        }
    });

}

Where mySQLconnection is the connection object you get after mysql.createConnection({}).

After that, you can promisify the function and use the promise like below :-

var sqlGunPromise = Promise.promisify(sqlGun);
sqlGunPromise(query, {}).then( function() {} );