Web SQL Database的异步机制
来源:互联网 发布:linux下python mmap 编辑:程序博客网 时间:2024/06/04 01:28
概述
Web SQL Database是一个主要基于异步的实现。其原理是, 发起SQL语句命令后, 不待结果传回, 立即将程序流程控制权转交给下一语句。SQL语句执行完毕后, 单独线程再调用回调函数, 返回查询结果。
什么意思呢? 看看下面的伪码:
var id = executeSql("SELECT ID FROM tableA");executeSql("SELECT * FROM tableB WHERE ID = ?", [id]);
我们需要先从表A中取出一个ID值并赋值于id, 接着, 希望使用这个id来进行下一步的查询。
由于异步工作机制, 这段代码是无法工作的。当第一个executeSql()语句发起后, 还未等结果出来, 就立即执行第二条executeSql()语句了。此时, id的状态是undefined, 当然无法进行正确的查询。
正确的做法应是将第二条语句放在一个回调函数中执行, 这样可确保只有等第一个查询结果出来后才执行第二条语句。
executeSql("SELECT ID FROM tableA", function(resultSet) { var id = resultSet.rows.item(0).ID; executeSql("SELECT * FROM tableB WHERE ID = ?", [id])});
这样, 就造成了嵌套会越来越长。且由于再加上很容易混淆的transaction()函数, 编写这样的代码又臭又长, 即难看,又容易出错。
本文通过简要地说明transaction()及executeSql()各个函数参数的作用, 从最简单的需求开始, 渐渐细化为功能较为齐全且代码结构清晰的一个解决办法。
关于transaction及readTransaction
void transaction(in SQLTransactionCallback callback, in optional SQLTransactionErrorCallback errorCallback, in optional SQLVoidCallback successCallback);interface SQLTransactionCallback { void handleEvent(in SQLTransaction transaction);};interface SQLTransactionErrorCallback { void handleEvent(in SQLError error);};interface SQLVoidCallback { void handleEvent();};
第一个SQLTransactionCallback用于使用所传入的tx。第二个可显示错误信息。第三个是当处理完整个transaction时, 统一回调callback函数。
关于executeSql函数
void executeSql(in DOMString sqlStatement, in optional ObjectArray arguments, in optional SQLStatementCallback callback, in optional SQLStatementErrorCallback errorCallback);interface SQLStatementCallback { void handleEvent(in SQLTransaction transaction, in SQLResultSet resultSet);};interface SQLStatementErrorCallback { boolean handleEvent(in SQLTransaction transaction, in SQLError error);};
由于执行Sql语句时, 有时需要返回查询结果, 因此SQLStatementCallback有一SQLResultSet的形参。可在这里将查询结果改为程序所需的各种形式。
结合使用transaction及executeSql
一个transaction可一并使用多个executeSql。因此, 可将多个Sql语句放在一个transaction执行完毕后, 整合多个Sql语句的结果, 再将该结果作为参数来调用transaction的successCallback。这样做,可较完美地利用并发机制。
db.transaction( function(tx) {}, // use tx function(error) {}, // handle error if any function() {} // this callback will be called if the transaction is committed);
再进一步:
db.transaction( function(tx) { tx.executeSql(); tx.executeSql(); ... }, function(error) {}, // handle error if any function() {} // call this callback if the transaction is committed);
现在,如何将tx.executeSql()的结果传给最后的函数里呢? 毕竟该函数没有形参。很简单, db.transaction()虽然很长, 但它毕竟只是一个函数。在此函数前声明一个变量, 用于保存tx.executeSql()的结果, 这样, 第三个回调函数也可以使用该结果了。
var result = {};db.transaction( function(tx) { tx.executeSql( "SELECT ID FROM ... WHERE ID = ?", [1], function(tx, resultSet) { result.id = resultSet.rows.item(0).ID; // save the selected ID in result.id }, function(tx, error) { console.log(error.code + error.message); } ); tx.executeSql(); ... }, function(error) {}, // handle error if any function() {} // call this callback if the transaction is committed);
tx.executeSql()共有4个参数。在第三个参数(该参数为函数)中, resultSet是执行查询完毕后所传回的结果, 可在这个函数中将查询结果保存至前面所声明的变量。第四个函数参数, 可用于即时检查执行Sql语句可能出现的错误, 如, Sql语句语法错误, 或往数据库中插入数据时, 出现了违反了键值唯一的错误,等等。这一步不要轻易省略, 可大大缩短调试时间。
第二个tx.executeSql()可灵活地执行另一相关的Sql语句。例如, 查询并返回多项记录。
var result = {};db.transaction( function(tx) { tx.executeSql( "SELECT ID FROM ... WHERE ID = ?", [1], function(tx, resultSet) { result.id = resultSet.rows.item(0).ID; // save the selected ID in result.id }, function(tx, error) { console.log(error.code + error.message); } ); tx.executeSql( "SELECT * FROM customer", [], function(tx, resultSet) { result.resultSet = resultSet; // save the whole resultSet in result.resultSet }, function(tx, error) { console.log(error.code + error.message); } ); ... }, function(error) {}, // handle error if any function() {} // call this callback if the transaction is committed);
如果事务执行过程中有任一错误, 就会将error传回db.transaction()的第三个函数参数。
var result = {};db.transaction( function(tx) { tx.executeSql( "SELECT ID FROM ... WHERE ID = ?", [1], function(tx, resultSet) { result.id = resultSet.rows.item(0).ID; // save the selected ID in result.id }, function(tx, error) { console.log(error.code + ", " + error.message); } ); tx.executeSql( "SELECT * FROM customer", [], function(tx, resultSet) { result.resultSet = resultSet; // save the whole resultSet in result.resultSet }, function(tx, error) { console.log(error.code + error.message); } ); ... }, function(error) { console.log("transaction error = " + error.code + ", " + error.message); }, function() {} // call this callback if the transaction is committed);
最后一步, 可在db.transaction()的第四个函数参数中使用上面声明的变量了。
var result = {};db.transaction( function(tx) { tx.executeSql( "SELECT ID FROM ... WHERE ID = ?", [1], function(tx, resultSet) { result.id = resultSet.rows.item(0).ID; // save the selected ID in result.id }, function(tx, error) { console.log(error.code + ", " + error.message); } ); tx.executeSql( "SELECT * FROM customer", [], function(tx, resultSet) { result.resultSet = resultSet; // save the whole resultSet in result.resultSet }, function(tx, error) { console.log(error.code + error.message); } ); ... }, function(error) { console.log("transaction error = " + error.code + ", " + error.message); }, function() { console.log(result.id); console.log(result.resultSet); });
当然, 如果嫌这个函数过长, 可将第四个函数参数分解为另一个单独的函数。
function doQueris() { var result = {}; db.transaction( function(tx) { tx.executeSql( "SELECT ID FROM ... WHERE ID = ?", [1], function(tx, resultSet) { result.id = resultSet.rows.item(0).ID; // save the selected ID in result.id }, function(tx, error) { console.log(error.code + ", " + error.message); } ); tx.executeSql( "SELECT * FROM customer", [], function(tx, resultSet) { result.resultSet = resultSet; // save the whole resultSet in result.resultSet }, function(tx, error) { console.log(error.code + error.message); } ); ... }, function(error) { console.log("transaction error = " + error.code + ", " + error.message); }, function() { onQuerriesFinished(result); } );}function onQueriesFinished(result) { console.log(result.id); console.log(result.resultSet);}
这里有两个函数: doQueris()及onQueriesFinished()。变量result成为doQueris()的局部变量。在doQueris()函数的事务执行完毕后, 通过传递result局部变量给onQueriesFinished()这个回调函数, 从而实现了将查询结果在不同的函数之间进行传递的效果。
最后, 只需简单地发起查询命令:
doQueris();
所有问题都会得到完美、有序的解决。
- Web SQL Database的异步机制
- web sql database 的例子
- HTML5 Web SQL Database 与 Indexed Database 的 CRUD 操作
- HTML5 Web SQL Database与Indexed Database的CRUD操作
- HTML5 Web SQL Database 与 Indexed Database 的 CRUD 操作
- HTML5 Web SQL Database 数据库的使用方法
- Web SQL Database
- Web SQL Database
- Web Sql Database 初探
- Web SQL Database
- Web SQL Database
- Web SQL Database
- Web SQL Database
- Web SQL Database 与 Indexed Database
- HTML5 Web SQL Database 数据库
- 前端数据库Web SQL Database
- Web SQL Database的基本使用方法
- HTML5的Web SQL DataBase本地数据库增删改查
- ViewDragHelper实现QQ5.0侧滑并处理与ViewPager的滑动冲突
- git stash简单介绍
- Codeforces Round #404 (Div. 2) C. Anton and Fairy Tale 贪心+二分
- 使用py2exe打包发布
- maven添加jar到项目中
- Web SQL Database的异步机制
- 垃圾收集器与内存分配策略
- POJ2001呵呵不好
- 覆盖索引
- 51nod 1478 括号序列的最长合法子段(栈-括号匹配寻找最长合法子串长度及其个数)
- 转载:移动前端开发之viewport的深入理解
- 文章标题
- go提问模板
- JPEG编码中的DCT与量化