jQuery没有按正确的顺序执行?

我最近开始使用jQuery,今天发现了一个奇怪的问题,它对我的​​行为如何。 据我了解,JavaScript是单线程的。 所以它的所有操作都应该以FIFO为基础运行。 但是,对我来说似乎并非如此。 请考虑以下事项。

SETUP如下

HTML:

3个div

  • div#1 =>包含可以单击以执行排序function的标题元素

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

  • div#3 =>包含一个基本的.gif文件,用于通知用户正在执行某些操作

jQuery – 包含执行DOM操作的sort函数。 基本上,它从HTML页面读取数据,存储在2D数组中,并对数组进行排序。 然后它使用排序数组中的数据完全清除div#2(数据div)并重建它。

预计执行情况如下

  • 用户单击其中一个标题以触发排序function
  • sort函数隐藏div#2并显示div#3
  • 执行排序function
  • 排序完成后,显示div#2(数据div),隐藏div#3

但是,这似乎发生了什么

  • 用户单击标题

  • 排序发生

  • 在最后一步隐藏和显示div

最初,由于我无法看到任何显示/隐藏的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是否改变了操作顺序以提高效率?

虽然“解决方案”完成了这项工作,但我不相信它是这种情况下的最佳解决方案。 有没有其他方法可以做到这一点? 如果需要,我可以提供可以certificate问题的工作代码示例。 谢谢。

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

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

要使更改显示,您必须结束脚本,然后在呈现器有机会显示更改后继续执行。

您可以使用setTimeout方法将控制权返回给浏览器,并尽快启动其余代码:

 $("#loadingIndicator").show(); $("#cases").hide(); window.setTimeout(function(){ doSort(columnNumber); //SORT $("#loadingIndicator").hide(); $("#cases").show(); }, 0); 

.show().show()是fx队列的成员,它是异步执行的,不会停止程序执行。

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

例如

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

JSFiddle的例子

ED:我不小心整个字。