【问题标题】:Callback, return value and HTML5 executeSql function回调、返回值和 HTML5 executeSql 函数
【发布时间】:2010-12-26 06:31:56
【问题描述】:

我有一个大问题。我知道这是关于回调,关闭,但我不知道如何解决这个问题。这是我的代码

$.Model.extend('Article',
{
     findAll : function(params, success, error){                
                var result = []
                db.transaction(function(tx) {
                    tx.executeSql('select * from contents', [],function(tx, rs) {
                        for(var i=0; i<rs.rows.length; i++) {
                            var row = rs.rows.item(i)
                            result[i] = {
                                id: row['id'],
                                title: row['title'],
                                body: row['body']
                            }
                        }
                    })
                })
                //here result is undefined
                alert(result)
                return result
    }
})
//undefined
var view = Article.findAll

我知道executeSql是异步函数,但是不知道executeSql如何保存和返回结果。我使用 javascript mvc 和 HTML 离线数据库。

感谢您的帮助

【问题讨论】:

  • 我在 Google 上搜索了“Javascript MVC”并找到了该库,但在 JavaScript MVC 文档中找不到有关“executeSql”的任何内容。如果你手头有文档,你应该检查一下是否有办法让 tx.executeSql 方法同步运行而不是异步运行。
  • 我知道executeSql也有同步方法,但是safari和其他基于webkit的浏览器只支持异步。下面的代码完美运行,谢谢你们
  • 完美运行?有人可能会说,这是“答案”? ;)
  • 同步 API 仅适用于(在规范中)网络工作者,而不是窗口对象,所以这是不可能的。 dev.w3.org/html5/webdatabase/#databases

标签: javascript html callback closures


【解决方案1】:

W3C Web 数据库规范讨论了对异步和同步数据库操作的支持。 (See 4.3 and 4.4)

如果您不能使用同步实现,那么您可能需要考虑这样解决问题:

$.Model.extend('Article',
{
     findAll : function(params, success, error){                
                var result = []
                db.transaction(function(tx) {
                    tx.executeSql('select * from contents', [],function(tx, rs) {
                        for(var i=0; i<rs.rows.length; i++) {
                            var row = rs.rows.item(i)
                            result[i] = {
                                id: row['id'],
                                title: row['title'],
                                body: row['body']
                            }
                        }

                        success(result); //toss the result into the 'success' callback
                    })
                })
                //here result is undefined
                alert(result)
                return result
    }
})

Article.findAll([], function(view) {
        //...
    }, function() {
        //error occured
    });

【讨论】:

  • 天哪,终于用你的代码工作了!重要的是我没有运行函数中的代码在外面!
【解决方案2】:

我也有同样的问题,但您可能想使用这个让生活更轻松的小型包装库;)

http://github.com/grosser/arjs

【讨论】:

    【解决方案3】:

    我遇到了同样的问题,尤其是在移动开发项目中。我创建了一个无需回调的库: http://code.google.com/p/proto-q/

    这使我的代码更容易排除故障、维护和增强。

    我添加了对 AJAX、网络工作者、脚本注入和存储 API 的支持。希望对你有帮助。

    【讨论】:

      【解决方案4】:

      您尝试同步使用结果,即您在定义之前访问结果(实际上在您的代码示例中它不是未定义的,它是一个空数组),但我希望那是因为您已将声明从其原始位置移动到弄清楚发生了什么。

      试试这个修改过的例子:-

      $.Model.extend('Article',
      {
          findAll : function(params, success, error){                
                  db.transaction(function(tx) {
                      tx.executeSql('select * from contents', [], function(tx, rs) {
                          var result = [];
                          for(var i=0; i<rs.rows.length; i++) {
                              var row = rs.rows.item(i)
                              result.push({
                                  id: row['id'],
                                  title: row['title'],
                                  body: row['body']
                              });
                          }
                          success(result);
                      });
                  });
          }
      });
      
      Article.findAll({}, function(result) { 
          // process result here
      });
      

      Article.findAll() 现在是一个异步函数,它的回调(闭包)接收结果。

      【讨论】:

      • 哦,我应该先阅读另一个示例,因为它本质上是相同的!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-25
      相关资源
      最近更新 更多