用于包装异步JavaScript函数以使其同步的模式

pfe*_*lbr 16 javascript iphone safari design-patterns mobile-safari

我正在使用JavaScript API,其中大多数函数都是异步的.API是WebKit JavaScript数据库API,它绑定到操作SQLite3数据库的功能子集.我理解设计决定使事情不同于阻止并提供响应式用户界面.在我的情况下,我知道我对异步API调用的使用将快速执行.由于这种情况,我想为我的开发人员提供一个更简洁,更易于使用的包装器API,强制同步调用.

这是异步调用

db.executeSql(sqlStatement, function(result) {
  // do something with result
});
Run Code Online (Sandbox Code Playgroud)

这就是我希望能够做到的

var result = dbWrapper.executeSql(sqlStatement);
// do something with result
Run Code Online (Sandbox Code Playgroud)

是否有设计模式/方式来做到这一点?编写或链接到代码示例是首选.目标平台/ broswer是iPhone上的Mobile Safari.

谢谢

bob*_*nce 10

抱歉,JavaScript不提供语言原语(例如,线程或协同程序)来使异步事件同步,反之亦然.

您通常只获得一个执行线程,因此您不能从计时器或XMLHttpRequest readystatechange获得回调,直到导致创建请求的一堆调用完全解开.

简而言之,你无法真正做到; 在您链接的WebKit页面上使用嵌套闭包的方法是我知道在这种情况下使代码可读的唯一方法.

*:除了在一些不起作用的模糊情况下,通常被认为是错误


小智 8

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");
}
Run Code Online (Sandbox Code Playgroud)

也许有点晚了,但当时技术并不存在;)


Mor*_*man 1

如果您使用 jQuery Ajax : $.ajax()

您可以将 asynch 属性设置为 false ,然后您将向服务器发出同步 ajax 请求。

  • 我确实查看了 jQuery 使用异步布尔值实现 $.ajax() 函数的方式,但事实证明它只是将异步参数传递给 XMLHttpRequest.open 函数,该函数是在“本机”代码中实现的(不是js),因此可以强制同步行为。 (2认同)