【问题标题】:Only the last run in a for loop in Javascript works只有在 Javascript 的 for 循环中最后一次运行有效
【发布时间】:2012-09-17 04:08:00
【问题描述】:

这是一个用 Javascript 编写的 for 循环。它正在尝试对 websql 应用查询。

for (var i = 0; i < 10; i++){
    db.transaction(function (tx){
    tx.executeSql('INSERT INTO ProjSetsT (ProjID) VALUES (?);', [i]);
    });
}

尝试很明显,我尝试将值“0, 1, 2, ... 9”添加到表 ProjSetsT 的 ProjID 列中。这是行不通的。我只得到了最后一个元素,即插入了“9”,但没有插入前八个数字。

有语法错误吗?

【问题讨论】:

  • 语法错误会阻止它完全运行... WebSQL 是一个异步 API,你不能指望它以这种方式捕获正确的值。见Web SQL Database + Javascript loop。此外,在一个事务中运行多个查询更快,并且实际上保证了插入顺序。在一个单独的事务中运行每个事务是一个缓慢的随机排序的免费的。
  • 为什么不做一次查询呢?其中绑定的值是根据 for 循环中的值构建的字符串。

标签: javascript html web-sql


【解决方案1】:

作为参数传递的每个函数都共享对i 的相同引用,因此每个新函数对象的i 值都会递增。给定异步上下文,i 将在您在循环中创建的第一个函数被调用之前达到其最大大小

您可以使用闭包来修复它:

for (var i = 0; i < 10; i++)
{
    db.transaction((function(privateI)
    {//privateI is unique for every function object
        return function (tx)
        {
            tx.executeSql('INSERT INTO ProjSetsT (ProjID) VALUES (?);', [privateI]);
        };
    })(i));//pass current value here
}

【讨论】:

    【解决方案2】:

    您有多个函数引用同一个 i 变量,最终为 10。

    每个函数都需要一个新的变量作用域。

    for (var i = 0; i < 10; i++){
        db.transaction(makeHandler(i));
    }
    
    function makeHandler(j) {
        return function (tx){
            tx.executeSql('INSERT INTO ProjSetsT (ProjID) VALUES (?);', [j]);
        };
    }
    

    现在i 被传递给makeHandler,它以j 接收它。

    每次调用makeHandler 时,它都会返回一个引用它自己的本地j 变量的函数。

    【讨论】:

      【解决方案3】:

      我认为db.transaction 可能会异步运行,因此可能会为您带来麻烦。您是否尝试过在事务中移动您的 for 循环?

      db.transaction(function (tx){
          for (var i = 0; i < 10; i++){
              tx.executeSql('INSERT INTO ProjSetsT (ProjID) VALUES (?);', [i]);
          }
      });
      

      【讨论】:

      • 你是对的。我认为这是最直接的方法,尽管其他人的建议都有效。这就是为什么我把你的作为答案。
      猜你喜欢
      • 2022-10-14
      • 1970-01-01
      • 1970-01-01
      • 2021-06-15
      • 2014-12-07
      • 2023-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多