函数不同步返回值

时间:2014-02-14 06:46:17

标签: javascript angularjs web-sql

我有以下条件,首先调用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

1 个答案:

答案 0 :(得分:3)

DBO.execQry是一个异步函数。您可能会因为回调模式而看到这种情况 - 例如execQry的第二个参数是一个函数,如果execQry准备好检索数据则调用该函数。我猜你所看到的是,console.log('retreiveAnalyticsData已结束');在console.log(analyticsData);

之前打印出来

如何处理?

1)oldschool方式将使用回调函数:

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;
}