【问题标题】:WebSQL error `SQL execution is disallowed` when chaining promises链接承诺时WebSQL错误“不允许执行SQL”
【发布时间】:2015-05-20 08:14:53
【问题描述】:

我知道这个标题有点拗口,但老实说,我无法为我的具体情况想出更好的标题(欢迎提出建议)。 所以基本上我记下了this JSFiddle(简化版)我面临的问题。我正在使用 AngularJS 的 $q.all 方法来收集一组依赖于查询结果的 Promise:

db.transaction(function(tx) {
    $q.all(fn(tx)).then(function(a) {
        console.log("Result:", a);
    });
});

其中fn 是一个返回承诺数组的函数。
在上述情况下,一切都按预期工作,结果(解析承诺的 sql 查询结果数组)是 console.logged 正确。
但是,如果我将$q.all 包装在另一个延迟对象的then 方法中,如下所示:

db.transaction(function(tx) {
    fn2(tx).then(function(tx) {
        $q.all(fn(tx)).then(function(a) {
            console.log("Result:", a);
        });
    });
});

我收到错误:Error: Failed to execute 'executeSql' on 'SQLTransaction': SQL execution is disallowed.
fn2 是一个仅返回一个解析为 tx 对象本身的承诺的函数。
我是否偶然发现了一个常见的陷阱?我搜索了一下,但没有找到任何东西。干杯。

【问题讨论】:

    标签: javascript angularjs promise web-sql


    【解决方案1】:

    这是因为当fn2 被解析时事务已经关闭。

    如果您不在fn2fn 中使用事务(甚至是同一个事务),它应该可以工作:

    db.transaction(function(tx) {
        fn2(tx).then(function(tx) {
            // new tranaction as the old one is closed
            db.transaction(function(tx) {
                $q.all(fn(tx)).then(function(a) {
                    console.log("Result:", a);
                });
            });
        });
    }); 
    

    看到这个fiddle

    【讨论】:

    • 谢谢。我明白了,但我不明白为什么在解决fn2 时事务应该关闭。此外,我提到这是一个简化的示例,但在我的实际场景中fn2 在事务tx 中执行查询;如果我根据您的示例发出一个新的“嵌套”事务并且其中的 sql 执行由于某种原因失败,那么已经关闭的旧事务是否会回滚或已经提交?这是我最关心的问题。
    • 我想我最好的选择是用 $q.all(fn(tx, fn2)) 替换 $q.all(fn(tx)) 并修改 fn 以便它接受一个事务和一个函数(或可能任何数量)并预先添加 fn2 的向$q.all 使用的promiseArray 承诺,因此没有链接,该过程基本上恢复到第一个工作示例。
    • 这就是 WebSQL 的工作原理。一旦回到事件循环,它就会关闭事务。是的,我想你的解决方案应该这样工作
    • 确实如此:jsfiddle.net/axedre/k7sr39kg/1。我将采用我的解决方案,因为 fn2fn 内部的查询必须在 same 事务中执行,因此如果有任何失败,整个事务也会执行。感谢您的帮助!
    猜你喜欢
    • 2015-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多