Я пытаюсь создать базу данных на моей угловой фабрике:
angular.module("App")
.factory("DatabaseFactory", function () {
var database = null;
var factory = {};
factory.getDatabase = function () {
if (database == null) {
window.sqlitePlugin.openDatabase({
name: "myDB.db",
androidDatabaseImplementation: 2,
androidLockWorkaround: 1
}, function (db) {
database = db;
database.transaction(function (transaction) {
transaction.executeSql(create_user, [], function (transaction, result) {
console.log("table user created: " + JSON.stringify(result));
}, function (error) {
console.log("table user error: " + error.message);
});
}, function (error) {
console.log("transaction error: " + error.message);
}, function () {
console.log("transaction ok");
return database;
});
});
} else {
return database;
}
}
return factory;
});
Создание базы данных работает, транзакция также одобрена. Теперь я предоставляю службе функцию для запуска базы данных:
angular.module("App")
.service("DatabaseService", function (DatabaseFactory) {
var database;
function initDatabase() {
console.log("init before database: " + JSON.stringify(database));
database = DatabaseFactory.getDatabase();
console.log("intit after database: " + JSON.stringify(database));
}
return {
initDatabase: function () {
initDatabase();
}
};
});
Он вызывается на устройстве:
angular.module("App", ["ionic", "ngCordova", "App.Home"])
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider.state("app", {
url: "/app",
abstract: true,
templateUrl: "templates/main.html"
});
$urlRouterProvider.otherwise("/app/home");
})
.run(function ($rootScope, $ionicPlatform, DatabaseService) {
$ionicPlatform.ready(function () {
console.log("ionic Ready");
if (window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if (window.StatusBar) {
StatusBar.styleDefault();
}
DatabaseService.initDatabase();
});
});
Выход журнала:
init before database: + undefined
init after database: + undefined
Таким образом, возврат базы данных на моей фабрике возвращается неопределенно, но я не знаю, почему. Он должен возвращать базу данных, так как она правильно инициализирована.
Вы не можете вернуть базу данных из функции, потому что получающая ее функция представляет собой асинхронный обратный вызов.
Вы можете использовать оператор return
только в том случае, если вся функция синхронна (например, не работает асинхронная работа, например, чтение из файлов, подключение к базам данных, сетевые запросы, сокеты и т.д.).
В вашем случае window.sqlitePlugin.openDatabase
выполняет некоторую асинхронную работу и запрашивает обратный вызов в качестве второго аргумента. Этот обратный вызов будет вызван после открытия соединения с базой данных, которое будет после getDatabase
функции getDatabase
.
window.sqlitePlugin.openDatabase({
name: "myDB.db",
androidDatabaseImplementation: 2,
androidLockWorkaround: 1
}, function (db) {
database = db
// this happens at some point in the future
});
// this happens straight away
// at this point database is still undefined
return database;
Хороший способ проверить это для дальнейшего использования - использовать console.log
чтобы узнать, в какое время и в каком порядке выполняется ваш код.
window.sqlitePlugin.openDatabase({
// ...
}, function (db) {
database = db
console.log('A');
});
console.log('B');
return database;
Вы увидите, что вместо того, чтобы выполняться в порядке написания инструкций, сначала регистрируется B
, затем A
second.
Если вы сделаете свой метод getDatabase
принятия аргумента обратного вызова, вы можете передать объект db
в него, как только он будет готов.
factory.getDatabase = function (callback) {
window.sqlitePlugin.openDatabase({
// ...
}, function (db) {
// do some stuff with db, when you are ready
// pass it to the callback, with null as the
// first argument (because there isn't an error
callback(null, db);
});
Затем вы переписываете свой код, чтобы использовать обратный вызов.
DatabaseFactory.getDatabase(function(err, db) {
console.log("intit after database: " + JSON.stringify(database));
});
Возможно, вам интересно, почему обратный вызов также имеет аргумент err
.
В node.js считается стандартной практикой обрабатывать ошибки в асинхронных функциях, возвращая их в качестве первого аргумента для текущего обратного вызова функции. Если есть ошибка, первый параметр передается объекту Error со всеми подробностями. В противном случае первый параметр имеет значение null.
(Из NodeJitsu)
Я думаю, вы должны заменить
var database = null;
var factory = {};
от
var factory = {};
и делай
return factory.database
в базе данных factory.getDatabase