问题
I want to get the callback of a successful SQLite transaction with Ionic 2. I am still currently learning the HTML5 Promise, and it is still a bit confuse. And since I've heavily used jQuery Deferred before, I try to adapt what I used to do with jQuery.
Before Ionic 2, I used the following jQuery pattern to execute my async SQL:
var SqlResult = function(sqlToExecute,bracketValues){
this.sqlToExecute = sqlToExecute;
this.bracketValues =bracketValues;
};
SqlResult.prototype.execSqlCustomDeferred = function(){
var execSqlCustomDeferredRes = $.Deferred();
var execSqlCustomDeferredResProm = execSqlCustomDeferredRes.promise();
var sqlToExecuteForTx = this.sqlToExecute;
var bracketValuesForTx = this.bracketValues;
DbManagement.db.transaction(function(tx){
tx.executeSql(sqlToExecuteForTx,bracketValuesForTx,success,error);
function success(tx,rs){
execSqlCustomDeferredRes.resolve(rs);
}
function error(tx,error){
execSqlCustomDeferredRes.reject(error);
}
});
return execSqlCustomDeferredResProm;
};
With that pattern I was getting the async result, with SqlResult.prototype.execSqlCustomDeferred.done(function(res){...})
.
Now I struggle to figure out how things should be ordered to use the Promise pattern, I thought of the following but it does not match:
This case would not work because resolve()
or reject()
don't exist (it doesn't transpile).
private execSqlCustom = (sqlToExecute:string,bracketValues:Array<any>) => {
let sqlToExecuteForTx:string = sqlToExecute;
let bracketValueForTx:Array<any> = bracketValues;
return this.db.transaction(
function(tx){
tx.executeSql(sqlToExecuteForTx,bracketValueForTx,success,error);
function success(tx,rs){
resolve(rs);
}
function error(tx,error){
console.log('execSqlCustom error ' + error.message);
reject(error);
}
}
);
This would not work neither because I think I'd lose the context (this) (it transpiles but at execution it tells me that:
it cannot read db of undefined
):
private execSqlCustom = (sqlToExecute:string,bracketValues:Array<any>) => {
let sqlToExecuteForTx:string = sqlToExecute;
let bracketValueForTx:Array<any> = bracketValues;
return new Promise(function(resolve,reject){
this.db.transaction(
function(tx){
tx.executeSql(sqlToExecuteForTx,bracketValueForTx,resolve,reject);
}
);
Does anyone spot what I've been doing wrong?
回答1:
I found that it could be added a .bind(this)
at the end of a function to carry within that function, the exisiting context (this).
By creating a new Promise()
and adding .bind(this)
at the end of the function(resolve,reject){}
within it, it worked and I can use .then( (...) => {...}
on the async result returned.
My function looks like that:
private execSqlCustom = (sqlToExecute:string,bracketValues:Array<any>):Promise<any> => {
return new Promise(function(resolve,reject){
this.db.transaction(
function(tx){
tx.executeSql(sqlToExecute,bracketValues,success,error);
function success(tx,rs){
resolve(rs);
}
function error(tx,error){
console.log('execSqlCustom error ' + error.message);
reject(error);
}
}
)}.bind(this)
);
}
来源:https://stackoverflow.com/questions/40347687/ionic-2-sqlite-manage-callback-with-promise