2

我有使用 indexedDB 的工厂和需要这个索引数据库来接收数据的方法 getRecipe。

问题是 indexedDB 在异步调用中返回它的实例,而 getRecipe 是另一种在异步调用中返回它的值的方法。

我试图通过承诺来解决它,但我失败了。

app.factory('RecipesStorage', ['$q', function($q) { 
var getDb = function () {
   var deferred = $q.defer();

   var db;
   var request = indexedDB.open('recipes', 1);

   request.onupgradeneeded = function (e) {
       console.log('Upgrading indexedDb');
       var thisDb = e.target.result;

       if (!thisDb.objectStoreNames.contains('recipe')) {
           thisDb.createObjectStore('recipe');
       }
   }

   request.onsuccess = function (e) {
       db = e.target.result;
       window.db = db;
       deferred.resolve(db);
   }

   request.onerror = function (e) {
       console.error('Error when opening indexedDB');
   }

   return deferred.promise;
};

var getRecipe = function (recipeId, callback) {
        getDb().then(function(db) {
            var transaction = db.transaction(['recipe'], 'readonly');
            var objectStore = transaction.objectStore('recipe');

            var data = objectStore.get(recipeId);

            data.onsuccess = function (e) {
                var result = e.target.result;
                console.log('GetRecipe:', result);
                callback(result);
            }

            data.onerror = function (e) {
                console.error('Error retrieving data from indexedDB', e);
            }
        });
};

return {getRecipe:getRecipe};
}]);

但这不起作用。在 getRecipe 中,函数 then 没有被调用。不知道哪里有问题。

4

3 回答 3

3

我们可以使用 Promise 链来使其工作。

(我没有数据库,所以我模拟了异步响应并用 包装了数据$q

演示Fiddle

fessmodule.controller('fessCntrl', function ($scope, RecipesStorage) {

    $scope.alertSwap = function () {
       RecipesStorage.getDb()
                        .then(function (result) {
                           $scope.data = result;                           
                        }, function (result) {
                            alert("Error: No data returned");
                        });
    }

});

fessmodule.$inject = ['$scope', 'RecipesStorage'];

fessmodule.factory('RecipesStorage', ['$q', function ($q) {

    var getDb = function () {        
        var data = [{
            "PreAlertInventory": "5.000000",
            "SharesInInventory": "3.000000"
        } ];   
        var deferred = $q.defer();
        deferred.resolve(data);
        return getRecipe(data);        
    };

    var getRecipe = function(db){    
        var data = [{        
            "TotalSharesBought": "0.000000",
            "TotalShareCost": "0.000000",
            "EstimatedLosses": "0.000000"
        }]; 
        db.push(data[0]);
        var deferred = $q.defer();
        deferred.resolve(db);
        return deferred.promise;
    }

    var factory = {
        getDb: getDb
    };

    return factory;
}]);

参考

在此处输入图像描述

  • 您可以链接承诺以创建代码流
  • 错误传播,因此您可以在链的末端捕获它

在此处输入图像描述

于 2013-11-10T15:31:42.077 回答
0

真正的问题是,在我的版本中,我在 1.0.8 版本中使用了 angular,但是当我将其切换到 1.2.0 版本时,它开始按预期工作。谢谢 :)

于 2013-11-11T18:54:24.283 回答
0

我在您的代码中看不到问题。也许这个 plunker可以帮助您找出问题所在。我根据您的代码创建了它,它显然有效。

于 2013-11-10T15:34:08.853 回答