WebSQL查询挂起,从不返回成功或错误回调

时间:2019-05-21 14:47:41

标签: ios cordova google-chrome web-sql angular1.6

我有一个Web应用程序的初始化过程,该过程以递归方式执行WebSQL查询。

它涉及一个名为actions的数组,并将几个函数推入该数组。每个函数都返回一个Promise,当执行WebSQL查询时,Promise将被解析。这些功能大多数涉及检查表是否具有应包含的所有列,如果没有,则删除表并使用正确的列配置重新创建。 (用户数据存储在服务器端,因此下一次登录将重新填充表。)

数组中的每个函数必须先完成执行,然后才能启动下一个函数。 actions数组中每个函数的基本骨架是:

actions.push(function() {
var d = $q.defer();
    Database.recreateTable(table).then(function() {
        d.resolve("Success");
    }, function(e) { d.resolve(e);});
    return d.promise
})

(即使数据库功能失败,该行也要解决,以确保仍对后续表进行检查。)

Database.recreateTable是Angular服务中的一个函数:

var recreateTable = function(table) {
    var def = $q.defer();
    execute("DROP TABLE IF EXISTS " + table).then(function() {
        createTable(table).then(function() {
            def.resolve();
        }, function(error) {
            ValidatorService.log(getScriptName(), error);
            def.reject(error);
        });
    }, function (error) {
        ValidatorService.log(getScriptName(), error);
        def.reject(error);
    });
    return def.promise;
}

其中createTable仅是以下内容:

var createTable = function(table) {
    var def = $q.defer();
    var q = "CREATE TABLE IF NOT EXISTS " + table + " (" + getColumns(table, true, true) + ")";
    execute(q).then(function(s) {
        def.resolve();
    }, function (error) {
        def.reject(error);
    });
    return def.promise;
}

execute是WebSQL事务的包装,涵盖了Web使用和Cordova使用:

var execute = function (query, bindings) {

    bindings = typeof bindings !== 'undefined' && typeof bindings !== 'null' ? bindings : [];
    var deferred = $q.defer();

    if (db === undefined || db === null) { //initialize first if hasn't been done yet
        init().then(executeQuery(), function(error) {} );
    }
    else {
        executeQuery();
    }

    function executeQuery() {
        if (window.cordova) {
            $cordovaSQLite.execute(db, query, bindings).then(function (result) {
                deferred.resolve(result);
            }, function (fail) {
                ValidatorService.log(getScriptName(), JSON.stringify(fail));
                deferred.reject(fail);
            });
        }
        else {
            db = window.openDatabase("database.db", '1.0', 'auto', 1024 * 1024 * 100);
            db.transaction(function(tx) {
                tx.executeSql(query, bindings, function (tx, result) {
                    deferred.resolve(result);
                }, function (tx, fail) {
                    deferred.resolve(fail);
                });
            });
        }
    }

    return deferred.promise;
}

actions数组中的所有函数都使用以下代码一个接一个地执行:

function executeRun() {
    var d = $q.defer();
    function multi(i) {
        if (actions.length > 0 && i < actions.length) {
            actions[i]().then(function(s) {
                multi(i+1);
            }, function(e) {
                multi(i+1);
            })
        }
        else {
            d.resolve();
        }
    }
    multi(0);
    return d.promise;
}

此刻,编写该指令以继续执行该操作是否成功,以便无论如何都将检查后续表。这些动作是一个接一个地执行的,而不是异步执行的,因为某些动作可能会或可能不会添加,具体取决于actions数组中的早期条目。

这背后的想法似乎很简单,但是问题是循环中进行了几次迭代,查询只是挂起而不返回响应,因此永远不会触发成功和错误回调。似乎没有任何押韵或原因在这种情况下发生,并且似乎仅在iOS Cordova上发生,当依赖于这些表的其他进程返回“无此表”错误时。 Android Cordova没有遇到此问题。

我以前曾在台式机Chrome浏览器中看到过这种情况,即使使用“清除站点数据”按钮也无法停止。唯一可以解决的问题是重新安装Chrome。

0 个答案:

没有答案