2

我在将行插入 SQL 数据库时遇到问题。我想将一组对象转换为 javascript 中的 SQL 表。

以下代码仅添加数组的第一个对象。我已经尝试了在 stackoverflow 和其他地方可以找到的所有内容,但无法使其正常工作。

任何帮助,将不胜感激。谢谢。

        for (var i = 0; i < arr.length; i++) {
            db.save({key:i+"", value:arr[i]}, function(e){

            });
        }

更新 1:我已将其更改为 mathec 的示例,并稍微缩小了问题范围。

插入的行数取决于插入对象的大小。所以它与处理每个对象所需的时间有关。

我该如何解决这个问题?谢谢。

更新 2:

我在下面采纳了 Robert Young 的建议,并附上了一个独立的例子。

下面的示例仅插入前 5 个元素。如果我删除了测试键中的一些单词文本,所以它只说“单词”一次,那么就会插入 10 个元素。所以现在我确定它与处理每个对象所需的时间有关。

<html>
    <head>
        <script src="jquery.js"></script>
        <script src="lawnchair.js"></script>
        <script type='text/javascript'>


            var db = "";
            var arr = [];

            arr.push({name:"a1", test:"word word word word word word word word word word word word word word "});
            arr.push({name:"a2", test:"word word word word word word word word word word word word word word "});
            arr.push({name:"a3", test:"word word word word word word word word word word word word word word "});
            arr.push({name:"a4", test:"word word word word word word word word word word word word word word "});
            arr.push({name:"a5", test:"word word word word word word word word word word word word word word "});
            arr.push({name:"a6", test:"word word word word word word word word word word word word word word "});
            arr.push({name:"a7", test:"word word word word word word word word word word word word word word "});
            arr.push({name:"a8", test:"word word word word word word word word word word word word word word "});
            arr.push({name:"a9", test:"word word word word word word word word word word word word word word "});
            arr.push({name:"a10", test:"word word word word word word word word word word word word word word "});
            arr.push({name:"a11", test:"word word word word word word word word word word word word word word "});

            $(function() {
                db = new Lawnchair({table:'t50'}, function(e){
                    for ( i = 0; i < arr.length; i++) {
                        (function(i) {
                            add_row(i);
                        }(i));
                    }
                });
            });

            function add_row(i) {
                db.save({key:i+"", value:arr[i]}, function(e){

                });
            }

        </script>
    </head>
    <body>

    </body>
</html>

更新 3:我使用了罗伯特建议的代码,并提出了以下与三个小元素一起使用的代码。所以我改变了第一个元素,使它比其他元素更大来测试它。第一个元素没有添加,最后两个是。处理数组有时间限制吗?

<html>
    <head>
        <script src="jquery.js"></script>
        <script src="lawnchair.js"></script>
        <script type='text/javascript'>

            var arr = [];
            var db = "";

            $(function() {
                db = new Lawnchair({table:'t51'}, function(e){
                    arr=[{key:"k1", value:"v1. Because the contents of this element are larger than the others it will not be added for some reason. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. "}
                    ,{key:"k2", value:"v2"}
                    ,{key:"k3", value:"v3"}]

                    db.batch(arr, function () {
                        db.all(function (recs) { for (r in recs) {console.log(recs[r].key +"| "+ recs[r].value) } });
                    });
                });

            });

        </script>
    </head>
    <body>
    </body>
</html>
4

3 回答 3

2

我犯了几次棘手的错误:-)。如果在循环内调用回调函数,它将被异步调用。因此,您的循环将一直执行到最后。解决这个问题的一种方法是围绕当前 i 值形成一个闭包,这样当回调函数执行时,它就会绑定到右边的 i。像这样的东西:

function doSomething(i) {
  console.log(i)
}

var i, len;

for ( i = 0; i < 10; i++) {
  (function(i) {
    doSomething(i);
  }(i));
}

循环内的函数将立即执行,但 i 值将保留在范围内。

于 2012-05-11T17:28:29.190 回答
1

首先,因为这是持久化存储,如果你一遍又一遍地运行它,你可能每次都得到不同的结果,因为你没有初始化持久化存储。最好添加一个db.nuke()以确保您从一张白纸开始,至少在您解决任何错误之前。

关于异步存储的主要知识是,仅仅因为函数返回并不意味着数据实际上已经存储。所以如果你跑

db = new Lawnchair(function(db){
    db.save({key:"value"})
    db.get("foo", function (rec) { console.log(rec.value) });
});

它可能有效,也可能无效,因为当您调用 db.get 时,可能会或可能不会存储该值。

为此,我们需要确保在调用 db.get 之前存储了该值。做到这一点的方法是使用回调——如果你将两个参数传递给 db.save,那么一旦值被存储,它将调用第二个参数。所以

db = new Lawnchair(function(db){
    db.save({key:"foo", value:"bar"}, function () {
        db.get("foo", function (rec) { console.log(rec.value) });
    });
});

工作正常。

当您尝试存储多个值时,这会变得很困难,因为您希望确保所有这些值都已存储。幸运的是,有一个功能batch

db = new Lawnchair(function(db){
    arr=[{key:"k1", value:"v1"},{key:"k2", value:"v2"},{key:"k3", value:"v3"}];
    db.batch(arr, function () {
        db.all(function (recs) { for (r in recs) {console.log(recs[r].key) } });
    });
});

应该输出

k1
k2
k3

尝试一下,看看会发生什么。

于 2012-05-12T05:51:04.537 回答
0

很难缩小问题的解决方案,因为我们不知道您如何将数据保存到数据库,可能是 AJAX 请求?但我认为问题在于异步保存数组的每一行的整个逻辑,因为代码不等待保存一行来开始另一行,所以发生了某种竞争条件,一些行保存在同一个“id”(自动增量字段)中,这解释了为什么只保存了一些行.

我的建议是将整个数组发送到服务器,然后保存每一行。

当然,您可以对每一行进行操作,首先锁定 id 然后保存数据,但这是一个坏主意,因为您需要为每一行往返于服务器和数据库,从而使对服务器的请求量翻倍。

希望能帮助到你!

PD +1 到@mathec 回答指出带有回调问题的循环变量!

于 2012-05-12T04:35:59.757 回答