我有以下条件,首先调用syncAnalytics
。在此函数中,还有另一个函数, retreiveAnalyticsData
,用于检索本地存储的数据。
但是在从retreiveAnalyticsData
返回值之前,函数syncAnalytics
的其余部分被执行。
DemoModule.factory('ApplicationAnalytics', function ($http, $location, DBO) {
return {
syncAnalytics: function () {
console.log("syncAnalytics called");// Getting displayed 1st
// Retrieve analytics data available data from db
var inputData = this.retreiveAnalyticsData();
console.log("Input Data : " + JSON.stringify(inputData)); // Getting displayed 4th
},
retreiveAnalyticsData: function () {
console.log('retreiveAnalyticsData called');// Getting displayed 2nd
// Select all rows from app_analytics table in db
var selectQuery = "SELECT * FROM app_analytics";
var analyticsData = [];
DBO.execQry(selectQuery, function (results) {
var len = results.rows.length,
i;
for (i = 0; i < len; i++) {
analyticsData.push(results.rows.item(i).text);
}
console.log(analyticsData); //Getting displayed 5th
return analyticsData;
});
console.log('retreiveAnalyticsData ended');// Getting displayed 3rd
}
};
});
所以基本上:
var inputData = this.retreiveAnalyticsData(); //This should be executed before the below line.
console.log("Input Data : " + JSON.stringify(inputData)); // Getting displayed 4th
任何见解将不胜感激。
注意:我正在使用AngularJS。
DBO.execQry 是一个异步函数。您可能会因为回调模式而看到这一点 - 例如,execQry 的第二个参数是一个函数,如果 execQry 准备好检索数据,则会调用该函数。我想你看到的是,那个控制台.log('retreiveAnalyticsData ended');在控制台之前打印出来.log(分析数据);
如何处理?
1)老派的方式是使用回调函数:
syncAnalytics: function () {
this.retreiveAnalyticsData(function(inputData){
console.log("Input Data : " + JSON.stringify(inputData));
});
},
retreiveAnalyticsData: function (callback) {
var selectQuery = "SELECT * FROM app_analytics";
var analyticsData = [];
DBO.execQry(selectQuery, function (results) {
var len = results.rows.length,
for (var i = 0; i < len; i++) {
analyticsData.push(results.rows.item(i).text);
}
callback(analyticsData);
});
}
但是这种方式有很多缺点。如果您想处理错误或需要进行多个异步调用或将它们同步在一起,该怎么办?所以我们来到了承诺模式。
2)$q的承诺模式
syncAnalytics: function () {
this.retreiveAnalyticsData().then(function(inputData){
console.log("Input Data : " + JSON.stringify(inputData));
});
},
retreiveAnalyticsData: function () {
var selectQuery = "SELECT * FROM app_analytics";
var analyticsData = [];
var deferred = $q.defer();
DBO.execQry(selectQuery, function (results) {
var len = results.rows.length,
for (var i = 0; i < len; i++) {
analyticsData.push(results.rows.item(i).text);
}
deferred.resolve(analyticsData);
});
return deferred.promise;
}