- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在使用 PhoneGap 和 jQuery Mobile。我试图从远程位置获取一些 JSON 数据,然后用它填充本地 WebSQL 数据库。这是我的 JS 函数:
function getLocations() {
var tx = window.openDatabase('csdistroloc', '1.0', 'Distro DB', 1000000);
tx.transaction(function(tx) {
tx.executeSql('DROP TABLE IF EXISTS locations'); //this line works!
tx.executeSql('CREATE TABLE IF NOT EXISTS locations (id, name, address, postalcode, phone, category)'); //this line works!
$.ajax({
url: "http://mydomain.com/api.php",
dataType: 'json',
data: { action: "getlocations" },
success: function(data) {
tx.executeSql("INSERT INTO locations (id, name, address, postalcode, phone, category) VALUES (2,'cheese','232','seven',5,6)"); //this line produces an error
}});
}, dberror, dbsuccess);
}
运行上面的函数在上面提到的行中给我一个错误“INVALID_STATE_ERR: DOM Exception 11”。当我实际尝试使用返回的 JSON 数据插入数据时,它会做同样的事情。我还尝试了 $.getJSON 技术,得到了完全相同的结果。
如有任何建议,我们将不胜感激!
最佳答案
尽管 accepted answer是正确的,我想对其进行扩展,因为我遇到了同样的问题,并且该答案没有说明为什么它不像 OP 那样工作。
当您在 Web SQL 中创建事务时,事务处理仅在 there are any statements queued up in the transaction 时保持事件状态。 .一旦事务中的语句管道干涸,引擎就会关闭(提交)事务。这个想法是当 function(tx) { ... }
回调运行时,
executeSql
是异步的,因此即使语句尚未执行,它也会立即返回。此时引擎注意到有语句在排队,并在关闭事务之前运行它们直到完成。在你的情况下,会发生什么:
executeSql
两次来排队两个语句。引擎运行它排队的两个语句。 ajax 请求也在异步运行,但它必须访问速度较慢的网络,因此它可能尚未完成。此时,语句队列为空,Web SQL 引擎决定是时候提交并关闭事务了!它无法知道稍后还会有另一个声明!当 ajax 调用返回并尝试执行 INSERT INTO locations
时,为时已晚,事务已经关闭。
已接受的答案建议的解决方案有效:不要在 ajax 回调中使用相同的事务,而是创建一个新事务。不幸的是,它有一个陷阱,你会期望使用 2 个事务而不是 1 个事务:操作不再是原子的。这对您的申请可能重要,也可能不重要。
如果事务的原子性对您很重要,您唯一的 2 个资源是:
在 ajax 回调内的一个事务中执行所有操作(所有 3 个语句)。
这是我推荐的。我认为等到 ajax 请求完成后再创建表很可能符合您的应用程序要求。
同步执行ajax请求as explained here .
我不推荐这样做。 JavaScript 中的异步编程是一件好的事情。
顺便说一下,我在 Promises 的上下文中遇到了这个问题,代码看起来像这样:
// XXX don't do this, it doesn't work!
db.transaction(function(tx) {
new Promise(function(resolve, reject) {
tx.executeSql(
"SELECT some stuff FROM table ....", [],
function(tx, result) {
// extract the data that are needed for
// the next step
var answer = result.rows.item( .... ).some_column;
resolve(answer);
}
)
}).then(function(answer) {
tx.executeSql(
"UPDATE something else",
// The answer from the previous query is a parameter to this one
[ ... , answer, .... ]
)
});
});
问题在于,对于 promises,链式 .then()
子句不会在原始 promise 解析后立即运行。它只是排队等候稍后执行,很像 ajax 请求。唯一的区别是,与缓慢的 ajax 请求不同,.then()
子句几乎立即运行。但是“几乎”还不够好:它可能会或可能不会运行得足够快以在事务关闭之前将下一个 SQL 语句滑入队列;因此,代码可能会或可能不会产生无效状态错误,具体取决于时间安排和/或浏览器实现。
太糟糕了:Promise
在 SQL 事务中使用会很有用。上面的伪示例可以很容易地在没有 promise 的情况下重写,但是一些用例可以极大地利用许多 .then()
链以及诸如 Promise.all
这可以确保整个 SQL 语句集合以任何顺序运行,但都在其他语句之前完成。
关于javascript - WebSQL 事务不会在 JS 回调函数中运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9953324/
我正在尝试使用当前日期和时间来执行 INSERT 和 SELECT 语句,但数据没有插入到 WebSQL 中。下面是我的代码: CREATION.. myDb.transaction(function
这是我在 stackoverflow 上的第一个问题。我尝试在这里和 Google 上搜索方法: 将文件转换为blob,将其保存在WebSQL中,然后从数据库中选择它并使用window.URL.cre
我正在使用以下语句在 Chrome 中创建一个 WebSQL 表: 'CREATE TABLE IF NOT EXISTS recs(id, fname,lname,email,country,com
所以我有一个 Javascript 类来包装和管理对 WebSQL 数据库系统的访问。 可以找到该类的代码:https://jsfiddle.net/dsct89kv/ 现在测试一下我正在使用的 fu
An online tutorial显示此交易: db.transaction(function (tx) { tx.executeSql('CREATE TABLE IF NOT EXISTS
我在循环方面遇到问题。我想实现以下步骤: 从网上下载一个巨大的 JSON 文件,然后我想循环遍历所有对象,并为每个对象(产品)从网上下载图像(使用 AJAX 调用)并填充 property obj.p
我正在尝试在 Phonegap 中创建一个应用程序并使用 WebSQL 创建本地数据库。我有一张名为“星星”的表...有很多 Actor /明星...在选择一颗星星的详细信息时,我想向其他相关明星(例
似乎无法弄清楚为什么这个简单的语句不起作用 tx.executeSql("INSERT INTO history SELECT * FROM scan"); 如果表历史记录为空,则它可以正常工作,这没
检查这个例子: var db = openDatabase( 'test.db', 1, '', 2*1024*1024 ); db.transaction(function(tx) { va
你好 friend ,我面临一个奇怪的问题。我开发 PHP 桌面应用程序, 我正在使用 websql 数据库。当我将数据提交到用户表中时 数据提交成功。但是当我提交到另一个表时数据却没有 提交的表结构
我正在尝试使用 WebSQL 和 JavaScript 执行登录功能。我写了一个函数,它接受一个参数(email)。该函数应该在数据库中搜索现有电子邮件,然后它应该返回一个警告,说明该电子邮件是否存在
我正在尝试使用复合主键在 websql 中创建一个数据库,但我似乎无法弄清楚此语句有什么问题: tx.executeSql('CREATE TABLE IF NOT EXISTS groepleden
我正在使用 WebSQL 和 IndexedDB 开发一个 Web 应用程序。 IndexedDB 在支持它的浏览器中运行良好,我的 WebSQL 实现在大多数浏览器中都可以运行,但是在 Androi
你好,我有一个工厂,它提供了与数据库一起使用的函数,它看起来像这样: .factory('DBwork', function () { var db = openDatabase("...");
这个问题已经有答案了: JavaScript closure inside loops – simple practical example (45 个回答) 已关闭 7 年前。 为什么我无法在事务中
我有以下代码来选择一行。当我用 getRecords("Peter Sam"); 调用函数时显示一条记录。但是,如果我只是通过 getRecords("Peter");它说“没有结果”。 getR
我在 iOS 上有一个使用 WebSQL 数据库的 PhoneGap 应用程序。在某些地方,我读到存储容量是 5MB,而在其他地方,我读到它是 50MB,有人可以帮我解决这个问题吗?我还计划在数据库中
https://www.w3.org/TR/webdatabase/#sqlstatementerrorcallback 看到这里sql语句错误回调定义了返回类型boolean: [Callback=
我正在使用 Web SQL 数据库构建应用程序。我记得在某处看到有一种方法可以使用 Google Chrome 来检查 Web SQL 数据库, 但是我找不到这样做的正确方法。 最佳答案 您可以使用
让我澄清一下,当我说移动网络应用程序时,我指的是旨在跨不同移动平台运行的网络应用程序,而不是访问互联网获取数据的 native 移动应用程序。 所以我正在阅读一些内容,看看这些移动网络应用程序如何在客
我是一名优秀的程序员,十分优秀!