在JavaScript / jQuery中,超时与内容加载异步调用倒计时的优缺点是什么?

What are the pros and cons of timeouts vs counting down with a content loading asynchronous call in JavaScript / jQuery

本文关键字:调用 异步 加载 倒计时 是什么 优缺点 jQuery JavaScript 超时      更新时间:2023-09-26

在我看来,我可能对递归解决方案进行了过度设计。

等待2秒等待第一组模块加载:

function loadContents() {
  $('[data-content]:not(.loaded)').each( function() {
    $(this).load($(this).data('content'));
    $(this).addClass('loaded');
  });
}
loadContents();
setInterval(loadContents, 2000);

当第一组模块全部加载完成后,检查是否有新的模块:

function loadContents() {
  var notLoaded = $('[data-content]:not(.loaded)'),
  notLoadedLength = notLoaded.length;
  notLoaded.each( function(i,element) {
    $(element).addClass('loaded');
    $(element).load($(element).data('content'), function() {
      // one more has been loaded
      notLoadedLength--;
      if (notLoadedLength == 0) {
        alert("countdown good");
        loadContents();
      }
    });
  });
}
loadContents();

您应该能够使用成功处理程序完成所有这些操作,而无需使用计时器轮询。

你不需要指定你想要做什么,但是如果你想并行加载多个东西,并且知道它们什么时候都加载了,那么你可以保留一些状态,告诉你已经加载了多少,当计数显示它们现在都加载了,你就知道你完成了。

如果您想顺序加载它们,那么您可以从每个成功处理程序中加载下一个。最简单的方法可能是创建一个要加载的东西的列表,然后用一个通用的成功处理器获取列表中的下一个东西,然后启动它的加载并从列表中移除它。当要加载的剩余项列表为空时,就完成了。

Edit:进一步查看您的代码,看起来您正在并行加载它们。您可以为每个正在加载的类创建一个成功处理程序,在该成功处理程序中添加已加载的类,并查看还有多少尚未完成。我的建议是:

function loadContents() {
  $('[data-content]:not(.loaded)').each( function() {
    var obj = $(this);  // save in local variable in function closure so we can reference it in the success handler
    obj.load(obj.data('content'), function() {
        obj.addClass('loaded');
        if ($('[data-content]:not(.loaded)').length == 0) {
            // all pieces of content are now loaded
        } else {
            // some pieces of content are still loading
        }
    });
  });
}
loadContents();

编辑2:好的,根据你的评论,我现在更好地理解这个问题了。我将loadContents的作用域设置为DOM树的父节点,然后在成功处理程序中新加载的内容上调用它。这将适用于无限级别,并且它是安全的,因为它只对DOM树的任何给定父级调用自己一次。当没有新内容要加载时,它就无事可做,因此不再调用自己。以下是我的建议:

function loadContents(root) {
  $('[data-content]:not(.loaded)', root).each( function() {
    var obj = $(this);  // save in local variable in function closure so we can reference it in the success handler
    obj.load(obj.data('content'), function() {
        obj.addClass('loaded');
        loadContents(obj);  // now load any contents from the newly loaded content
    });
  });
}
loadContents(document.body);   // start it off by looking in the whole DOM tree