在开发手机PhoneGap应用程序时,我有一个有趣的问题.我需要从数据库中查询大约10个数据项(通过PhoneGaps sqlite API)…像许多
javascript API一样,这是异步的.当您进行查询时,您将传入“成功”处理程序.
现在,在这种情况下,我的偏好是一个同步查询方法,只有在完成时才会返回.然后我可以写出直线代码,一个接一个地查询10个项目中的每一个.
由于PhoneGap的异步性质(真的,我看到这遍遍JS),我被迫写了一个如下所示的野兽:
db.query( "SELECT...",success() { db.query( "SELECT...",success() { db.query( "SELECT...",success() { db.query( "SELECT...",success() { db.query( "SELECT...",success() { } } } } }
这只是我不得不去的一半(并大大简化了…)…当我在C中使用sqlite时,我可以简单地做一些类似的事情:
db.query( "SELECT...",resultA ); db.query( "SELECT...",resultB ); db.query( "SELECT...",resultC ); db.query( "SELECT...",resultD ); db.query( "SELECT...",resultE );
在我看来,成功处理方法是伟大的,当你只需要去1或2级深度…但是,当你需要更多的时候完全崩溃…
他们的图书馆还是图书馆的特色,使这更容易?
解决方法
这是一个在社区中普遍存在的一个问题,即许多
and libraries模式与之形成对抗.
我最喜欢的是承诺我在几个事件中作了解决异步问题的承诺,作了介绍;您可以在SlideShare:Callbacks,Promises,and Coroutines (oh my!): The Evolution of Asynchronicity in JavaScript上查看我的幻灯片.它还解释了为什么需要异步,简而言之,因为JavaScript是单线程的.
对于您给出的特定示例,请查看幻灯片53及其旁边.简而言之,假设db.query返回一个承诺,它将如下所示:
db.query("SELECT...") .then(function (a) { return db.query("SELECT..." + a); }) .then(function (b) { return db.query("SELECT..." + b); }) .then(function (c) { return db.query("SELECT..." + c); }) .then(function (d) { return db.query("SELECT..." + d); }) .then(function (e) { return db.query("SELECT..." + e); });
当然,如果您不需要使用下一个查询的结果,则会变得更好:
Q.all([ db.query("SELECT..."),db.query("SELECT..."),db.query("SELECT...") ]).spread(function (a,b,c,d,e) { // ... });