使用webSQL(SQLite)的phonegap代码中有问题的承诺

时间:2017-01-03 11:28:36

标签: javascript sqlite cordova promise web-sql

我在与Phonegap / Cordova的错误中挣扎。我在连接的设备中构建和测试我的应用程序,这是我得到的错误:

INVALID_STATE_ERR:DOM例外11

我发现的解决方案都没有效果。他们中的大多数都是针对使用ajax,而这并非如此。我发现了另一个关于phonegap的问题,他们说这可能是因为设备没有准备就绪,但我已经检查过设备是否准备就绪。

这是抛出错误的代码(我使用Promise polyfill BTW,因为到目前为止Cordova不支持它):

/**
 * Clients insertion
 * @param tx
 * @param clientes
 * @return {Promise}
 */
clientes = function(clientes) {

    return new Promise(function(resolve, reject) {
        var clientesCount = clientes.length;

        if (clientesCont === 0){
            resolve();
        }
        else {
            APP.db.transaction(function(tx) {
                $.each(clientes, function(i, cliente) {

                    var idclienteLocal;

                    // Current client
                    tx.executeSql("INSERT OR REPLACE INTO clientes (id, name, ...) " +
                        "VALUES " +
                        "(?,?,...)",
                        [cliente.id, cliente.name],
                        function(tx, res) {

                            clientesCount--;

                            idclienteLocal = res.insertId;

                            // Clien phones
                            telefonosCliente(tx, cliente, idclienteLocal).then(function() {
                                // Client credits
                                creditosCliente(tx, cliente, idclienteLocal).then(function() {
                                    if (clientesCount === 0) {
                                        resolve();
                                    }
                                }).catch(function(error) {
                                    reject('Error créditos cliente ' + cliente.empresa + ': ' + error);
                                });
                            }).catch(function(error) {
                                reject('Error teléfonos cliente ' + cliente.empresa + ': ' + error);
                            });

                        }, function(tx, error) {
                            reject(error.message);
                        });

                });
            });
        }
    });
}

我怀疑它可能与循环有关(我为此使用了jQuery),所以我尝试通过使用递归函数对前一个迭代完全解析后的每个迭代进行排队,但它没有&甚至可以在浏览器中工作(在第一个procesarCliente()调用中的Promise,在clientes()中不会得到解决)。这是修改过的代码:

/**
 * Recursive function to process each client one after the other
 * @param tx
 * @param clientes
 * @param cliente
 * @return {Promise}
 */
procesarCliente = function(tx, clientes, cliente) {
    return new Promise(function(resolve, reject) {
        // Current client
        tx.executeSql("INSERT OR REPLACE INTO clientes (id, name, ...) " +
            "VALUES " +
            "(?,?,...)",
            [cliente.id, cliente.name,...],
            function(tx, res) {
                var idclienteLocal = res.insertId;

                // Client phones
                telefonosCliente(tx, cliente, idclienteLocal).then(function() {
                    // Client credits
                    creditosCliente(tx, cliente, idclienteLocal).then(function() {                         
                        if (clientes.length === 0) {
                            resolve();
                        }
                        else {
                            procesarCliente(tx, clientes, clientes.shift());
                        }
                    }).catch(function(error) {
                        reject('Error créditos cliente ' + cliente.empresa + ': ' + error);
                    });
                }).catch(function(error) {
                    reject('Error teléfonos cliente ' + cliente.empresa + ': ' + error);
                });

            }, function(tx, error) {
                reject(error.message);
            });
    });
},
/**
 * Clients insertion 
 * @param tx
 * @param clientes
 * @return {Promise}
 */
clientes = function(clientes) {

    return new Promise(function(resolve, reject) {
        var cliente,
            clientesCont = clientes.length;

        if (clientesCont === 0){
            resolve();
        }
        else {
            APP.db.transaction(function(tx) {
                cliente = clientes.shift();
                procesarCliente(tx, clientes, cliente).then(function() {
                    resolve();
                }).catch(function(error) {
                    reject(error);
                });
            });
        }
    });
}

有关修复第二种方法的任何帮助,最重要的是,如何让它在phonegap中运行?

修改

我已经添加了一个验证码来检查本地数据库中的每个表,而且令人惊讶的是,它显然只创建了两个名为" undefined"和"项目" (我甚至没有使用这样的表格。)

此处的验证码:

    if (APP.DEBUG) { // this is true
        // Verify inserted data when triggered event 'app.load.all' just after the very last item in the DB has been inserted
        $wrapper.on('app.load.all', function() {
            APP.db.transaction(function(tx) {
                console.log('Verifying DB');
                tx.executeSql("SELECT name FROM sqlite_master WHERE type='table'", [],
                    function(tx, res) {
                        if (res.rows.length) {
                            $.each(res.rows, function(i, tabla) {
                                if (tabla.name !== '__WebKitDatabaseInfoTable__') {
                                    console.log('Verifying table ' + tabla.name);
                                    tx.executeSql("SELECT * FROM " + tabla.name, [],
                                        function(tx, res) {
                                            console.log("Table " + tabla.name + " has " + res.rows.length + " records");

                                        },
                                        function(tx, error) {
                                            console.log('Error verifying table ' + tabla.name + ':' + error.message);
                                        });
                                }
                            });
                        }
                    }, function(tx, error) {
                        console.log('Error verifying DB tables: ' + error.message);
                    });
            });
        });
    }

这导致这些行被" Web控制台":

过滤
I/Web Console(14391): Verifying DB:1085
I/Web Console(14391): Verifying table undefined:1091
I/Web Console(14391): Verifying table item:1091
I/Web Console(14391): Error Verifying table undefined:no such table: undefined:1100
I/Web Console(14391): Error Verifying table item:no such table: item:1100

这对我来说非常奇怪

1 个答案:

答案 0 :(得分:0)

我终于找到了问题:

我可以将浏览器中的SQLResult对象视为数组,但这显然不适用于phonegap构建(可能是因为Android WebView浏览器)。因此,实际上没有插入记录。

我不得不摆脱jQuery循环(他们没有得到Phonegap应用程序中的每个项目),而是使用for循环,最终使用 item() SQLResult 对象的方法:

<强> BAD:

$.each(res.rows, function(i, item) {
   //...
}

不可

var item;
for (var i = 0; i < res.rows.length; i++) {
   item = res.rows.item(i);
}