Vibhas Vibhas - 2 months ago 10
Javascript Question

Using result of one function to call other in bluebird promises

I am working on nodejs and converting my model callbacks to promises as much as possible by keeping response data same to controller so that I don’t need to change controller logic.So I need to use callbacks which I know is a bad idea while working with bluebird.

var functions={
checkifexists:function(data){
return new Promise(function(resolve,reject){
// Query is fired here
resolve(data) or reject (data)
});
},
create:function(data,cb{
mysql.getConnectionFromPool(function(err,connection){
this.checkifexists(data,connection).then(function(res){
if(res.count)
{
cb(res.count);
}
else
{
connection.query(insertsql,data,function(err,data){
// Handle any error or return insertID
cb(null,insertID)
});
}
}).catch(function(e){
console.log(e);
}).finally(function(){
connection.release();
});
});}


Based on accepted answer Sample Controller Code:

sampleModel.create(req.body,function(err,result){
console.log("Err : "+err); // Always Null
console.log("Result :"+result); // Always displays both reject and resolve cases
});


In above code there is one checkifexists function and a create function but from controller only create function is called so I adjusted by code accordingly but still it looks messy.

Is it the right way to do it ? What if I need to call series of function but one after another so that I may pass response of one function to another and so on .

Answer

Instead of dealing manually with callbacks you should use asCallback. Promisify your node-style connection things, and use promises wherever you can.

var functions = {
    getConnection: function() {
        return Promise.fromCallback(mysql.getConnectionFromPool.bind(mysql))
        .disposer(function(connection) {
            connection.release();
        });
    },
    checkifexists: function(data, connection) {
        return new Promise(function(resolve,reject) {
            // Query is fired here  
            resolve(data) or reject (data) 
        }); 
    },
    insert: function(data, connection) {
        return Promise.fromCallback(connection.query.bind(connection, insertsql, data));
    },
    create: function(data, cb) {
        return Promise.using(this.getConnection(), function(connection) {
            return this.checkifexists(data, connection)
            .then(function(res) {
                if (res.count) {
                    throw res.count; // are you sure?
                } else {
                    return this.insert(data, connection);
                }
            }.bind(this))
        }.bind(this))
        .asCallback(cb); // this is all you need
    });
};