我编写了一个打开indexedDB的函数。我使用了一个承诺,因为我认为这是处理这个问题最干净的方法。
this.$get = function($q, $rootScope, $window) {
return {
finalize: function() {
var deferred = $q.defer();
var dbRequest = $window.indexedDB.open(dbName, dbVersion);
dbRequest.onupgradeneeded = function(event) {
// XXX do something here.
};
dbRequest.onsuccess = function(event) {
db = event.target.result;
console.log('Success!');
deferred.resolve(event);
};
dbRequest.onerror = deferred.reject;
return deferred.promise;
}
};
};
为了测试这个,我创建了以下测试函数:
describe('finalize', function() {
it('should initialize the database', function(done) {
var promise = resource.finalize();
promise.then(function() {
console.log('resolved');
var transaction = resource.db.transaction(['Component']);
expect(transaction).toBeDefined();
done();
});
$rootScope.$apply();
});
});
这会在控制台中打印'Success!'
,但承诺永远不会解决。
如果我将$rootScope.$apply()
移动到onsuccess函数的末尾,则解析承诺,但仅针对一个测试。然后其他测试会抛出错误Error: [$rootScope:inprog] $digest already in progress
。
我该如何解决这个承诺?回调函数更好吗?
答案 0 :(得分:2)
this.$get = function($q, $rootScope, $window) {
return {
finalize: function() {
var deferred = $q.defer();
var dbRequest = $window.indexedDB.open(dbName, dbVersion);
dbRequest.onupgradeneeded = function(event) {
// XXX do something here.
};
dbRequest.onsuccess = function(event) {
db = event.target.result;
console.log('Success!');
$rootScope.$apply(function () {
deferred.resolve(event);
});
};
dbRequest.onerror = function (error) {
$rootScope.$apply(function () {
deferred.reject(error);
});
}
return deferred.promise;
}
};
};
你也应该使用var promise = resource.finalize();一次性进行所有测试