Контроллер выполняется до того, как завод даст результат

Со ссылкой на этот ответ Как мне вернуть ответ от асинхронного вызова? Как я мог реализовать это в моем секанрио.

Я пытаюсь выполнить кэширование с использованием sqlite с помощью плагина cordova 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;
});

1 ответ

Запрос выполняется асинхронно. Под этим я подразумеваю, что когда вы вызываете CURD.exec_query(), запрос ставится в очередь, и как только он ставится в очередь, ваш метод продолжает выполняться с "return ($scope.deferred.promise).then(function(pricelists){ Msgstr "Вот почему 4, 5, 6 отображаются перед 2 и 3. Как только запрос завершается, снова, асинхронно, вызывается метод".then () ", когда 2 и 3 оповещаются.

Обратите внимание, что getBrandDocs () будет возвращать ДО того, как будет вызван метод.then (). То, что вы могли бы сделать, это сделать так, чтобы ваш метод.then () генерировал событие, которое асинхронно регистрируется в вызывающем коде, который, в свою очередь, выполняет шаги 4, 5 и 6.

Другие вопросы по тегам