用于包装异步JavaScript函数以使其同步的模式
Pattern for wrapping an Asynchronous JavaScript function to make it synchronous
我使用的是JavaScript API,其中大多数函数都是异步的。API是WebKit JavaScript数据库API,它绑定到操作SQLite3数据库的功能子集。我理解设计决策,使事情异步,从而不阻塞并提供响应用户界面。在我的情况下,我知道我对异步API调用的使用会执行得很快。既然是这种情况,我想为我的开发人员提供一个更干净、更容易使用的包装器API,强制同步调用。
这是异步调用
db.executeSql(sqlStatement, function(result) {
// do something with result
});
以下是我想做的
var result = dbWrapper.executeSql(sqlStatement);
// do something with result
有没有设计模式/方法可以做到这一点?最好是编写或链接到代码的示例。目标平台/浏览器是iPhone上的Mobile Safari。
感谢
抱歉,JavaScript没有提供语言原语(例如线程或协程)来使异步事物同步运行,反之亦然。
您通常只获得一个执行线程,因此在导致创建请求的调用堆栈完全分解之前,您无法从计时器或XMLHttpRequest readystatechange获得回调。
简而言之,你不可能真正做到这一点;在您链接的WebKit页面上使用嵌套闭包的方法是我所知道的在这种情况下使代码可读的唯一方法。
*:除了在一些对你没有帮助的模糊情况下,通常被认为是错误
StratifiedJS允许您做到这一点。
甚至还有一篇关于如何将其应用于浏览器存储的文章:http://onilabs.com/blog/stratifying-asynchronous-storage
这是它使用的分层JavaScript库https://gist.github.com/613526
示例如下:
var db = require("webdatabase").openDatabase("CandyDB", ...);
try {
var kids = db.executeSql("SELECT * FROM kids").rows;
db.executeSql("INSERT INTO kids (name) VALUES (:name);", [kids[0]]);
alert("done");
} catch(e) {
alert("something went wrong");
}
也许有点晚了,但当时这项技术还不存在;)
您可以尝试以下操作:
function synch()
{
var done = false;
var returnVal = undefined;
// asynch takes a callback method
// that is called when done
asynch(function(data) {
returnVal = data;
done = true;
});
while (done == false) {};
return returnVal;
}
但这可能会在异步方法期间冻结您的浏览器。。。
或者看看Narrative JavaScript:Narrative JavaScript是JavaScript语言的一个小扩展,它支持异步事件回调的阻塞功能。这使得异步代码具有令人耳目一新的可读性和可理解性
http://neilmix.com/narrativejs/doc/index.html
Mike
如果您使用的是jQuery Ajax:$.ajax()
您可以将asynch的属性设置为false,然后您将有一个到服务器的同步ajax请求。
我们使用GWT RPC,它也有一个异步API。我们目前用于串行进行几个异步调用的解决方案是调用链:
callA(function(resultA) {
callB(resultA, function(resultB) {
callC(); //etc.
});
});
这种嵌套方法实现了您想要的内容,但对于新手来说,它冗长且难以阅读。我们研究的方法之一是将我们需要进行的调用添加到堆栈中,并按顺序执行:
callStack = [
callA(),
callB(),
callC()
];
callStack.execute();
然后调用堆栈将管理:
- 调用串行调用(即第一个示例中的布线)
- 将结果从一个调用传递到下一个调用
然而,由于Java没有函数引用,调用堆栈上的每个调用都需要一个匿名类,所以我们没有这样的解决方案。然而,您可能会在javascript方面取得更大的成功。
祝你好运!
这实际上并没有实现数据库查询的同步操作,但这是我的简单管理解决方案。基本上将调用函数用作回调函数,并测试results参数。如果函数接收到结果,它会解析它们;如果没有,它会将自己作为回调发送到查询方法。
render: function(queryResults){
if (typeof queryResults != 'undefined'){
console.log('Query completed!');
//do what you will with the results (check for query errors here)
} else {
console.log('Beginning query...');
this.db.read(this.render); //db.read is my wrapper method for the sql db, and I'm sending this render method as the callback.
}
}
我不确定这是否是正确的地方,但我在这里搜索在Firefox中进行同步调用的答案。解决方案是删除onreadystatechange回调并直接调用。这就是我的发现和解决方案与休息服务的同步回调
- Javascript,访问一个主要对象模块模式中的每个对象
- 是否有任何snippet或jQuery插件可以列出easylist.txt模式匹配的DOM中的所有元素
- 试图在引导模式内动态生成图表,得到offsetWidth错误
- 同位素库错误:未捕获错误无布局模式包装生产线8
- 在控制器和数据对象之间同步数据
- 同步调用,直到用户通过angular验证为访问者
- javascript函数同步
- 在DOM中查找一个模式并替换它's的内容使用jquery
- 如何缩短MongoDB ObjectId并在Mongoose模式中使用它
- 同步/异步AJAX函数的模式
- 在nodejs中,是否有更好的设计模式来同步调用异步函数
- 我需要帮助在同步模式下调用FB.api()
- 同步实例化模式——将JSON扁平化为实际的循环数据结构
- 使用模式承诺jquery将异步函数更改为同步函数
- 我可以告诉浏览器同步始终使用一个.html文件吗?(用于html5模式链接)
- 是否有一个模式来管理javascript同步和异步调用
- NodeJs,用于同步开发的模式
- 如何使用同步令牌模式来防止CSRF安全
- 同步模式下的WebSQL..有可能吗
- 用于包装异步JavaScript函数以使其同步的模式