参考这个答案How do I return the response from an asynchronous call?我怎么能在我的secanrio中实现这个。
我正在尝试使用cordova sqlite插件使用sqlite进行缓存,但我的问题是我的控制器在我的工厂完成执行之前执行。我正在粘贴我的控制器代码和我的工厂代码。我知道执行的顺序已经提醒了。我理想的警报序列是1,2,3,4,5,6但是当我执行代码时,我得到的警报序列如1,5,6,2,3,4。我正在粘贴下面的控制器和工厂代码。
angular.module('foo').controller('PriceListController',["$scope","$http","$stateParams","CURD","$q","DB", function($scope,$http,$stateParams,CURD,$q,DB) {
$scope.brand_id=Number($stateParams.id);
$scope.process=true;
$scope.pricelists=[];
$scope.getBrandDocs= function(){
var parameters=new Array(2);
parameters[0]=$scope.brand_id
parameters[1]=1;
CURD.exc_query("select * from brand_docs where brand_id=? AND type=?",parameters)
.then(function(price_lists) {
alert("2");
$scope.inter_pricelist=price_lists;
console.log("Records from query call:"+JSON.stringify( $scope.inter_pricelist));
$scope.deferred = $q.defer();
if ($scope.inter_pricelist){
console.log("Found data inside cache", JSON.stringify($scope.inter_pricelist));
$scope.deferred.resolve($scope.inter_pricelist);
// alert(JSON.stringify( $scope.inter_pricelist));
alert("3");
}
else{
$http.get('http://foo.com?brand='+ $scope.brand_id +'&type=price_list')
.success(function(data) {
//alert("http call");
console.log("Received data via HTTP",JSON.stringify(data));
angular.forEach(data.data.info, function(value, key) {
var sql = "INSERT OR REPLACE INTO brand_docs(id, brand_id, name, file_url,type) VALUES (?, ?, ?, ?, ?)";
var parameters=new Array(5);
parameters[0]=value.id;
parameters[1]=value.brand_id;
parameters[2]=value.name;
parameters[3]=value.file_url;
parameters[4]=value.type;
var result=DB.query(sql,parameters);
});
$scope.deferred.resolve(data.data.info);
})
.error(function() {
console.log("Error while making HTTP call.");
$scope.deferred.reject();
});
}
return ($scope.deferred.promise).then(function(pricelists){
alert("4");
return pricelists;
},function(){});
},function(){});
alert("5");
};
$scope.pricelists=$scope.getBrandDocs();
alert("6");
}]);
//这是我粘贴的工厂代码
angular.module('foo').factory('DB', function($q, DB_CONFIG,$cordovaSQLite) {
var self = this;
self.db = null;
self.init = function() {
try{
self.db = window.sqlitePlugin.openDatabase(DB_CONFIG.name, '1.0', 'database', -1);
angular.forEach(DB_CONFIG.tables, function(table) {
var columns = [];
angular.forEach(table.columns, function(column) {
columns.push(column.name + ' ' + column.type);
});
var query = 'CREATE TABLE IF NOT EXISTS ' + table.name + ' (' + columns.join(',') + ')';
self.query(query);
console.log('Table ' + table.name + ' initialized');
});
}
catch(err){
}
};
self.query = function(query, bindings) {
bindings = typeof bindings !== 'undefined' ? bindings : [];
console.log("Query:"+query+" bindings:"+ bindings);
var deferred = $q.defer();
self.db.transaction(function(transaction) {
transaction.executeSql(query, bindings, function(transaction, result) {
console.log("Query sucessfull :"+ query);
console.log("Result of Query:"+ JSON.stringify(result));
deferred.resolve(result);
}, function(transaction, error) {
console.log("Error:"+ JSON.stringify(error));
deferred.reject(error);
});
});
return deferred.promise;
};
self.fetchAll = function(result) {
var output = [];
for (var i = 0; i < result.rows.length; i++) {
output.push(result.rows.item(i));
}
//console.log("RECORDS:" +JSON.stringify(output));
return output;
};
self.fetch = function(result) {
return result.rows.item(0);
};
return self;
})
.factory('CURD', function(DB) {
var self = this;
self.all = function(table_name) {
return DB.query('SELECT * FROM '+table_name)
.then(function(result){
return DB.fetchAll(result);
});
};
self.exc_query = function(query,parameters) {
return DB.query(query,parameters)
.then(function(result){
return DB.fetchAll(result);
});
};
self.getById = function(id,table_name) {
return DB.query('SELECT * FROM '+table_name +' WHERE id = ?', [id])
.then(function(result){
return DB.fetch(result);
});
};
return self;
});
答案 0 :(得分:0)
查询以异步方式完成。我的意思是,当你调用CURD.exec_query()时,查询排队,一旦排队,你的方法继续执行&#34; return($ scope.deferred.promise).then(function( pricelists){&#34;。这就是为什么4,5,6出现在2和3之前的原因。一旦查询完成,再次,异步,&#34; .then()&#34;方法是被叫,这是2和3被警告的时候。
请注意,getBrandDocs()将返回BEFORE,然后调用.then()方法。你可以做的是让你的.then()方法发出一个在调用代码中异步拾取的事件,然后执行4步,5步和6步。