0

I've following two async operations and then final onResult and onFault defined. How can I chain following two async operations getConnection and then select and then finally calling onResult or onFault

Edit need help in promisifying following sequence.

    new Promise(this.getConnection)
        .then(this.select)
        .then(this.onResult)

getConnection: function(resolve, reject) {
    console.log('get connection')
    if(database = common.model.connections.Sync.getConnection()) {
        database.transaction(function(transaction){
            resolve(transaction);
        });
    } else {
        reject("Connection Error");
    }
},

select: function(transaction) {
    console.log('select', transaction)
    var self = this;

    var query = "SELECT * FROM configuration WHERE key = 'schedule'";
    self.transaction.executeSql(query, [], function(transaction, resultSet){self.selectTransactionComplete(transaction, resultSet)}, function(){self.selectTransactionError()});
},

selectTransactionComplete: function(transaction, resultSet) {
    console.log('select transaction complete')
    if(resultSet.rows.length == 0) {
        this.onResult(false);
    } else if(new Date().getTime() - new Date(common.Config.getLastSync()).getTime() > resultSet.rows.item(0).value) {
        this.onResult(true);
    }
},

selectTransactionError: function(error) {console.log(this.constructor.NAME, this.selectSQL); console.log(error);},

onResult: function(data) {
    console.log(data);
},

onFault: function(info) {
    console.log(info)
}
user2727195
  • 7,122
  • 17
  • 70
  • 118
  • You appear to be using promises like callbacks. Don’t; return them instead. `asyncAction`, for example, should either return a promise or pass two arguments (neither of which can throw directly) to `then`. – Ry- Dec 09 '14 at 20:36
  • 1
    [**What is the deferred anti-pattern and how do I avoid it?**](http://stackoverflow.com/questions/23803743/what-is-the-deferred-antipattern-and-how-do-i-avoid-it) – Benjamin Gruenbaum Dec 09 '14 at 20:37
  • removed asyncAction as it was out of the scope, how can I reach from `getConnection` to `onResult` call via these two async operations - `getConnection` & `select`, just like here http://www.html5rocks.com/en/tutorials/es6/promises/ (queueing async operations) – user2727195 Dec 09 '14 at 20:47
  • appreciate any help using written code in context of my example, I've gone through articles, understand single asyn but still stuck and confused for multiple queued async operations, I noticed `Promise.all` but not sure if this will work in my case – user2727195 Dec 09 '14 at 20:52
  • after reading couple of things, please review my attempt below in my answer, is this how it's supposed to be? – user2727195 Dec 09 '14 at 21:25
  • @minitech I realized what you mean by using promises like callbacks, I revised my attempt in my answer below, however, there's an inherit problem with promises which is forcing me to not to use it in my already structured code, that is, let' say after `onResult` anywhere in my code if i have exception it's going to be suppressed, reason it's part of promise chain, however I want out of the chain and get into my normal coding routine but once I'm in promise, I'm in the chain, and any errors are silently ignored, to reproduce the issue inside `onResult` type `throw "error"` – user2727195 Dec 09 '14 at 22:25

2 Answers2

0

after trying couple of things, is this how it's supposed to be done? please review

    this.getConnection()
        .then(this.select, this.getConnectionError)
        .then(this.selectTransactionComplete, this.selectTransactionError)

getConnection: function() {
    console.log('get connection')

    var promise = new Promise(function(resolve, reject){
        try {
            database = common.model.connections.Sync.getConnection();
            database.transaction(function(transaction){
                resolve(transaction);
            });
        } catch(error) {
            reject("Connection Error");
        }
    });

    return promise;
},

getConnectionError: function(info) {
    console.log("connectionError");
    this.onFault();
},

select: function(transaction) {
    console.log('select')
    var self = this;

    var promise = new Promise(function(resolve, reject){
        var query = "SELECT * FROM configuration WHERE key = 'schedule'";
        transaction.executeSql(query, [], function(transaction, resultSet){resolve(resultSet)}, function(error){reject(error)});
    });

    return promise;
},

selectTransactionComplete: function(resultSet) {
    console.log('selectTransactionComplete')

    /*if(resultSet.rows.length == 0) {
        this.onResult(false);
    } else if(new Date().getTime() - new Date(common.Config.getLastSync()).getTime() > resultSet.rows.item(0).value) {
        this.onResult(true);
    }*/
},

selectTransactionError: function(error) {
    console.log('selectTransactionError')
    //console.log(this.constructor.NAME, this.selectSQL);
    //console.log(error);
},

onResult: function(data) {
    console.log('onResult')
},

onFault: function(info) {
    console.log('onFault')
}
user2727195
  • 7,122
  • 17
  • 70
  • 118
0

If you are using a promise library like q, the way you would go about chaining the promises is as below;

getConnection: function() {
    var deferred = Q.Defer();
    console.log('get connection')

        try {
            database = common.model.connections.Sync.getConnection();
            database.transaction(function(transaction){
                deferred.resolve(transaction);
            });
        } catch(error) {
            deferred.reject("Connection Error");
        }

    return deferred.promise;
}

when you call you would do something like below;

Q.when(getConnection)
.then(function(result){
 // handle success or resolve
}, function(error){
 // handle rejection.
};

Also I suggest reading the common js promises specification

Jerome Anthony
  • 7,823
  • 2
  • 40
  • 31
  • 1
    thanks Jerome for the code, however, I'm looking to do the same in native JavaScript promise – user2727195 Dec 09 '14 at 22:12
  • The `Q.when` is redundant (just call getConnection). Moreover if you use Q.Promise (in new versions of Q) instead of deferreds you won't need to type that try/catch it'll do it for you. – Benjamin Gruenbaum Dec 09 '14 at 22:18
  • Thanks for the comments guys. May I ask why you want to do vanilla JS when there are good libs implemented for this? – Jerome Anthony Dec 09 '14 at 22:37