当嵌套在 JS 中时——不再定义“while 循环”变量

When nesting in JS-"while loop" variable is not defined anymore

提问人:Corbinian 提问时间:11/17/2023 更新时间:11/17/2023 访问量:38

问:

我的 JS 脚本检查数据库是否有值。如果没有,它将填充数据库。再次触发时,数据库中的值将显示在页面上。当我通过重新加载页面运行脚本两次时,这有效。当我但整个事情在一段时间内循环时,它根本不起作用。循环永远运行,因为我想它不能进入我不确定这是否是作用域问题,我只是无法弄清楚,为什么当 while 循环处于活动状态时它的行为不同。marmaInfo.onsuccess = function(evt) {

var key = $('#marmaID').val();
console.log("key " + key );
store = getObjectStore("marmasStore", 'readwrite');

let i = 0;
//while (i < 1) {
    var marmaInfo = store.get(key);
    marmaInfo.onsuccess = function(evt) {
        var req = store.openCursor(key);
        var record = evt.target.result;
        console.log("record:", record);
        req.onsuccess = function(e) {
          var cursor = e.target.result; 
          if (cursor !== null) { // key already exist
            console.log(key + " FOUND");
            console.log("load and display values of " + key);
            data = marmaInfo.result
            //build page
            // Marma information
            document.getElementById("headline").innerHTML = data.sanskrit;
            console.log("display values of " + key + " DONE");
            i++;
          } else { // key not exist
            console.log(key + " NOT FOUND");
            console.log("initial filling DB ...");
            initialMarmaData.forEach((marma) => {
                var request = store.put(marma);
                request.onsuccess = (event) => {
                    console.log(event.target.result + " initial filling DB DONE");
                };
            //return;
            });
            //store.add(obj)
          }
        };
    };
    marmaInfo.onerror = function(evt) {
        console.log("error");
        i++;    
    }
//}

javascript while 循环 索引数据库

评论

1赞 David 11/17/2023
你到底想通过这样的循环完成什么?该循环正好包含 3 行代码(3 个操作)。(1)从商店取货。(2-3) 它将事件处理程序分配给它获取的内容。它只是无限地重复这两个操作,因为它们都没有修改 的值。你是想在事件处理程序放一个循环吗?(还是在第一个事件处理程序中分配的事件处理程序内部?i
0赞 Barmar 11/17/2023
请记住,and 回调函数是异步执行的,而不是在循环执行时执行的。onsuccessonerror
1赞 Barmar 11/17/2023
我认为你想要的是递归,而不是循环。将代码放在命名函数中。然后回调可以再次调用它重试。onerror
0赞 Corbinian 11/17/2023
@David感谢您的回答。基本上只是最内在的if语句需要循环。我检查钥匙是否存在。如果是这样,请执行一些操作并设置 i=1。如果没有,请创建密钥并再次运行 if 语句。则密钥存在,应执行操作。但是我需要在if语句之前进行所有操作,以再次查找密钥。最后一部分不起作用。
0赞 Corbinian 11/17/2023
@Barmar 谢谢!递归是解决方案。我在下面发布了更新的代码。

答:

0赞 Corbinian 11/17/2023 #1

@Barmar有正确的想法,它就可以与递归一起使用。非常感谢@Barmar

这是递归的代码:

let i = null;
function recurse() {
    i++;
    console.log("loop " + i);
    var key = $('#marmaID').val();
    console.log("key " + key );
    store = getObjectStore("marmasStore", 'readwrite');
        var marmaInfo = store.get(key);
        marmaInfo.onsuccess = function(evt) {
            var req = store.openCursor(key);
            var record = evt.target.result;
            req.onsuccess = function(e) {
                var cursor = e.target.result; 
                  if (cursor !== null) { // key already exist
                    console.log(key + " FOUND");
                    data = marmaInfo.result
                    //build page
                    document.getElementById("headline").innerHTML = data.sanskrit;
                    console.log("display values of " + key + " DONE");
                  } else { // key not exist
                    console.log(key + " NOT FOUND");
                    console.log("initial filling DB ...");
                    initialMarmaData.forEach((marma) => {
                        var request = store.put(marma);
                        request.onsuccess = (event) => {
                            console.log(event.target.result + " initial filling DB DONE");
                        };
                    });
                      if (i > 2) {
                        return;//this is just for savety
                      }
                    recurse()
                  }
            };
        };
        marmaInfo.onerror = function(evt) {
            console.log("error");
            return; 
        }
};
//}
recurse()