【问题标题】:JavaScript For loop inusual behaviourJavaScript For 循环异常行为
【发布时间】:2014-07-01 13:22:11
【问题描述】:

我有一个带有 html 内容的 jsp 文件和一个脚本,我也在使用 dhtmlx。我的 Web 应用程序的其他部分正在运行,因此,我只想专注于这个问题,因为环境运行良好。在我得到的文件的一个点中:

numTabs = getNumTabs();
for (var i=0; i<numTabs;i++) {
    var mytab = "tab_"+i;
    tabbar.addTab(mytab,'Tab Numer: ' + i,'');
    //alert("for " + i); PLACE 1
    initTabContent(mytab);
}

function initTabContent(tabID){
    //alert("initTabContent " + i); PLACE 2
    tab = tabbar.cells(tabID);
    toolbar = tab.attachToolbar();
    toolbar.loadXML('.../...file.xml',function(){
           //alert(i); PLACE 3
           toolbar.setItemText('botton1', 'Botton 1');

    });
    grid = tab.attachGrid();
    //more stuff
}

重点是:

如果我取消注释 PLACE 1 中的警报,一切都会很顺利,它会加载 XML 并且一切正常,但如果我评论警报,它不会顺利。

如果我取消注释警报 1 和警报 2,我会在网页中看到:

  1. 我看到:“为 0”-> 好的
  2. 我看到:“for 1”几乎立即变为“initTabContent 0” -> 好的,但我可以看到它
  3. 我看到:“for 1” -> 好的
  4. 我看到:“for 2”几乎立即更改为“initTabContent 1”-> OK
  5. 我看到:“for 2”-> 好的
  6. 我看到:“for 3”几乎立即变为“initTabContent 2”-> OK ....然后

所以,我知道尽管使用了 myfunction,循环仍在继续,并且不会等待该函数的完全终止。 有趣的是,如果我评论警报 1 和 2,然后取消评论警报 3,我在网页上看到的第一件事就是 4,然后是 3、2、1、0...

如果我再次离开,只有警报 1 未注释,一切正常。我想的原因是警报使系统等待用户,因此 XML 加载良好。

我的问题: 第一:为什么循环不等待函数完成?应该是顺序的吧? 第二:没有警报如何解决?我还尝试在里面放一个空的 for 循环以腾出时间,但没有成功……(这不是一个好方法)

非常感谢, 亚历克斯。

【问题讨论】:

  • 它不是顺序的 - 它是异步的。 loadXML 方法发出 AJAX 请求(我猜),并在完成时执行提供的函数(无论何时)。
  • 您忘记了一些需要它们的特定变量上的var
  • 如我之前所说,缺少的变量是全局的,这只是一个片段。
  • 他们失踪的事实是整个问题。 toolbar = tab.attachToolbar(); 将在加载 xml 之前被覆盖。
  • @KevinB 你是完全正确的。那个 var 不见了。我没有检查的原因是因为它与循环内的警报一起工作,那怎么可能呢?如果没有定义 var,它如何通过警报停止循环?

标签: javascript html jsp web-applications dhtmlx


【解决方案1】:

给您带来麻烦的部分原因是“警报”会阻止执行,而 loadXML 调用是异步的。 要更准确地描述按什么顺序发生的事情,请使用 console.log 而不是 alert。

您是否尝试在调用 myFunction 中将 i 的值用于警报以外的其他目的?

如果是这样的话。尝试替换:

myfunction(i);

与:

(function (num) { return function() {myfunction(num)} })(i);

【讨论】:

  • 尽管 loadXML 调用是异步的,但我仍然不明白为什么该调用会倒退。我使用控制台日志并且没有错误。错误是 for 循环不会等待 myfunction 完成并再次调用它。我需要 i 的值,因为代码比我给出的示例要复杂一些。你能重写替换吗?因为我不明白。非常感谢。 @BrandoTheBrave
  • @Alek 在更新我的答案之前我有几个问题:工具栏是什么类型的对象?它是一个 Xml 文档吗?你在什么浏览器上测试这个?你在使用任何 XML 库吗?
  • 这是一个 DHTMLX 工具栏,我正在使用这些库。工具栏是从 XML 文件加载的,因为它有更多按钮,所以......在 myfunction 中,我给它们命名和可见性属性。我认为问题的解决方案是强制循环等待。我尝试了一个while循环,每次myfunctions返回true时,我都有一个i++让while循环继续。但是结果是一样的,还是不行……
  • 我不认为你会有很多运气迫使循环等待。 DHTMLXtoolbar.loadXML 的设计方式可以防止这种情况。您可以做的是使用 onLoadFunction 调用一个函数来跟踪加载的 xml 的数量,并且当所有这些都已加载时,您可以循环浏览工具栏对象。您的示例代码并不代表您遇到的问题。如果您可以修改您的示例,我可以提出更具体的建议。
  • 基本上,取决于 numTabs,我必须创建这么多标签。在每个选项卡中,我需要放置一个带有按钮的工具栏,之后,我需要在其下放置一个网格。网格出现了,工具栏也出现了,但是由于 for 循环与 loadXML 函数相比非常快,因此有些功能无法正常工作,例如按钮的名称。将警报放入循环中,停止循环等待用户,并且 loadXML 函数有足够的时间来完成它必须做的所有事情。
【解决方案2】:

感谢@KevinB,我意识到整个jsp 文件中确实缺少toolbar 声明。 toolbar = tab.attachToolbar(); 在加载 XML 之前被覆盖。

现在有了**var** toolbar = tab.attachToolbar();,问题就解决了。

要查看循环无法正常运行的原因,您可以阅读问题下的 cmets。

【讨论】:

    猜你喜欢
    • 2013-07-30
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    • 2021-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-09
    相关资源
    最近更新 更多