【问题标题】:How to show a busy indicator for a long non-ajax operation?如何为长时间的非 ajax 操作显示繁忙指示器?
【发布时间】:2014-07-31 23:25:31
【问题描述】:

我有一个在客户端上运行 2-3 秒的函数(没有 ajax 调用)。 我正在尝试在此操作运行时显示“忙碌/处理中”动画。

简化代码如下:

var ajaxContainer = $('.spinner');
// show
$(ajaxContainer ).show();

// long operation
var items = GetItems();
$.each(items, function (index, value) {
    ProcessItem(value.itemID);
});

// hide
$(ajaxContainer ).hide();

但这并没有按预期工作。我得到的结果是操作在没有显示微调器的情况下运行。虽然它确实显示了操作结束的时间。

我在网上看到一些帖子提到这可以通过使用 windows.setTimeout() 来完成。但由于此操作基于动态数量的项目,我不想提前设置特定的超时数。相反,我想在操作开始时显示微调器,并在完成时隐藏它。

有没有一种优雅的方法来实现这一点?

【问题讨论】:

  • 你的长操作是同步的还是异步的?
  • 同步。它基本上是一个 $.each() 循环。
  • 请贴出长操作的代码。
  • 如果它是同步和阻塞的,你所要做的就是在代码执行之前显示一个微调器,并在之后删除?
  • 据我所知,同步操作将始终锁定 UI(这意味着同时显示不会更新)。如果您希望 UI 保持交互性,则必须采取一些措施使其异步 stackoverflow.com/questions/9516900/…(我自己从未尝试过,否则我会将其作为答案发布)

标签: javascript jquery ajax html client-side


【解决方案1】:

我认为您必须向ProcessItem 函数添加一个回调参数,以检查是否所有项目都已处理。试试这个方法:

function ProcessItem(id, callback){
    //do process and after call callback function 
    callback(); 
}

var processedItemsQuantity = 0;
var ajaxContainer = $('.spinner');
ajaxContainer.show();
// long operation
var items = GetItems();
$.each(items, function (index, value) {
    ProcessItem(value.itemID, function(){ 
        if (items.length - 1 == processedItemsQuantity){
            ajaxContainer.hide();
        } 
        else processedItemsQuantity++;
    });
});

【讨论】:

  • 我不明白这是如何解决问题的?所以我不明白赞成票吗?显然,如果相同 ajaxContainer.hide(); 则处理所有项目;在 $.each 方法之后调用?我认为问题不仅仅是隐藏容器,因为作者说“我得到的结果是操作运行没有显示微调器。虽然它确实显示了操作结束的时间。”
  • @MaunoV。这是一个异步过程,在这种情况下,您无法在 $.each 方法之后显示微调器。如果这样做,您将永远看不到微调器,因为它隐藏得太快(项目正在处理中)。在处理最后一项后,您必须隐藏微调器。
  • 好吧,好吧。有兴趣听听本主题作者的 cmets :)。不知道它是否有效,我认为长时间操作是同步的,我想这只是我的错误。
【解决方案2】:

您不能在同步操作中显示微调器,因为它会阻塞 UI(ajax 是异步的,这就是它起作用的原因)。

您需要将代码放入Web Worker

【讨论】:

    猜你喜欢
    • 2011-04-08
    • 1970-01-01
    • 1970-01-01
    • 2015-07-31
    • 2012-05-28
    • 1970-01-01
    • 2012-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多