首页 文章

Angular Factory返回null

提问于
浏览
0

我正在尝试在我的角度工厂中 Build 一个数据库:

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

因此我工厂中数据库的返回返回undefined,但我不知道为什么 . 它应该返回数据库,因为它已正确初始化 .

2 回答

  • 1

    您无法从函数返回数据库,因为接收它的函数是异步回调 .

    如果整个函数是同步的(例如,不执行任何异步工作,例如从文件读取,连接到数据库,网络请求,套接字等),则只能使用 return 语句 .

    在您的情况下, window.sqlitePlugin.openDatabase 执行一些异步工作和asks for a callback as the second argument . 在数据库连接打开后将调用此回调,这将在 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 秒 .

    如果使 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

  • 0

    我认为你应该更换

    var database = null;
    var factory = {};
    

    通过

    var factory = {};
    

    并做

    return factory.database
    

    在您的factory.getDatabase中

相关问题