2010-10-20 61 views
5

我最近开始使用jQuery,今天发现了一个奇怪的问题,它是如何为我表现的。据我所知,JavaScript是单线程的。所以它的所有操作都应该以FIFO为基础运行。但是,这似乎并不适合我。请考虑以下事项。jQuery没有以正确的顺序执行?

SETUP是如下

HTML:

3的div

  • DIV#1 =>包含可点击来执行排序功能

  • 首标元素

    div#2 =>包含需要排序的数据

  • DIV#3 =>包含用于通知正在执行

jQuery的 一些操作的用户的基本.gif要点 - 包含排序函数确实DOM操作。基本上,它从HTML页面读取数据,存储在二维数组中,并对数组进行排序。然后它完全清除div#2(data div),并使用来自排序数组的数据重建它。

EXECUTION预计是如下

  • 用户点击标题之一来触发排序功能
  • 排序函数隐藏DIV#2和示出DIV#3
  • 排序功能是执行
  • 一旦排序完成,div#2(data div)被显示,div#3被隐藏

然而,这里是什么似乎发生

  • 用户点击标题

  • 排序发生

  • 隐藏和申报单的表现发生在最后一步

最初,由于我无法看到任何div显示/隐藏,我假设它发生得太快,我不能注意到。所以我给jQuery的.show()和.hide()函数添加了时间延迟。一旦完成,很明显,展示和隐藏行动正在结束。

*解* 一番搜索后,我好不容易如我所料通过使用jQuery .queue()和.dequeue()函数来得到这个工作。这里的致命弱点是我必须在每次操作之间插入1毫秒的延迟。然后,只有这样,浏览器才能够按照我的意愿隐藏/显示div。因此,操作又是这样的:

var theQueue = $({}); // jQuery on an empty object 

theQueue.queue("testQueue", 
       function(next) { 
        $("#loadingIndicator").show(); 
        $("#cases").hide(); 
        next(); 
       } 
      ); 
theQueue.delay(1, "testQueue"); 

theQueue.queue("testQueue", 
       function(next) { 
        doSort(columnNumber); //SORT 
        next(); 
       } 
      ); 
theQueue.delay(1, "testQueue"); 

theQueue.queue("testQueue", 
       function(next) { 
        $("#loadingIndicator").hide(); 
        $("#cases").show(); 
        next(); 
       } 
      ); 

theQueue.dequeue("testQueue"); 

}

我肯定不会对此事的专家,但我认为操作应该以相同的顺序执行,因为他们被称为。浏览器没有按照正确的顺序渲染? jQuery是否改变操作的顺序以使事情更有效率?

尽管“解决方案”完成了这项工作,但我并不认为这是这种情况下的最佳解决方案。有没有其他方法可以做到这一点?如果需要,我可以提供能够证明问题的工作代码示例。谢谢。

另一方面,我注意到大数据集,当用户点击一个头元素来触发排序时,浏览器变得没有反应。我意识到它正在执行排序功能,但我希望有一种方法可以避免这种情况。有什么想法吗?

回答

7

这些操作的执行顺序与它们被调用的顺序相同,但问题在于DOM元素和屏幕上显示的内容是两个单独的东西。将元素呈现在屏幕上的过程与Javascript代码在同一单线程环境中运行,因此在脚本完成之前它不能在sceen上显示任何更改。

要让更改显示出来,您必须结束脚本,然后在渲染器有机会显示更改时恢复它。

可以使用setTimeout方法来控制返回给浏览器,并获得代码的其余部分尽快启动:

$("#loadingIndicator").show(); 
$("#cases").hide(); 

window.setTimeout(function(){ 

    doSort(columnNumber); //SORT 
    $("#loadingIndicator").hide(); 
    $("#cases").show(); 

}, 0); 
+0

太棒了,谢谢你的易于解释。我现在正在使用这种方法,我必须说它使用的代码少于我使用的其他队列方法。干杯。 – Harinder 2010-10-21 14:09:50

1

.show().hide()是FX队列,这是成员不会中止程序执行,而是异步执行。

效果可能会通过链接按顺序排队,但其他代码将独立于fx队列执行而执行。以您想要的方式获取操作顺序的方法是像您一样创建自定义队列,或者为每个效果使用回调函数。

E.g.

$('#loadingIndicator').show(250,function(){ 
    $('#cases').hide(250,function(){ 
     doSort(columnNumber); 
    }).show(250, function(){ 
     $('#loadingIndicator').hide(250);}) 
}); 

JSFiddle example

ED:我不小心整个单词。

+0

谢谢你的洞察力。我相信这个自定义队列信息将在不久的将来派上用场。 – Harinder 2010-10-21 14:11:33