jQueryasynchronous函数调用,没有AJAX请求
这似乎很愚蠢,但我无法find如何做一个与jQuery不涉及一些服务器端请求的asynchronous函数调用。 我有一个缓慢的函数遍历了很多的DOM元素,我希望浏览器在这个函数运行时不会冻结。 我想在慢速函数被调用之前显示一个小指针,然后当慢速函数返回时,我想隐藏指示器。 我有以下几点:
$('form#filter', parentNode).submit(function() { var form = $(this); indicator.show(); var textField = $('input#query', form); var query = jQuery.trim(textField.val()); var re = new RegExp(query, "i"); slowFunctionCall(); // want this to happen asynchronously; all client-side indicator.hide(); return false; });
目前我提交表单,指标不显示,浏览器冻结,然后slowFunctionCall
完成。
编辑:我用Vivin的答案 ,特别是Sitepoint链接来获得以下解决scheme:
var indicator = $('#tagFilter_loading', parentNode); indicator.hide(); var spans = $('div#filterResults span', parentNode); var textField = $('input#query', parentNode); var timer = undefined, processor = undefined; var i=0, limit=spans.length, busy=false; var filterTags = function() { i = 0; if (processor) { clearInterval(processor); } indicator.show(); processor = setInterval(function() { if (!busy) { busy = true; var query = jQuery.trim(textField.val()).toLowerCase(); var span = $(spans[i]); if ('' == query) { span.show(); } else { var tagName = span.attr('rel').toLowerCase(); if (tagName.indexOf(query) == -1) { span.hide(); } } if (++i >= limit) { clearInterval(processor); indicator.hide(); } busy = false; } }, 1); }; textField.keyup(function() { if (timer) { clearTimeout(timer); } /* Only start filtering after the user has finished typing */ timer = setTimeout(filterTags, 2000); }); textField.blur(filterTags);
这显示并隐藏指标,也不冻结浏览器。 您可以观看隐藏的DOM元素,这正是我所要做的。
Javascript运行在一个单一的线程,因此,如果你有一个缓慢的function, 将阻止其他一切。
UPDATE
这将做一些你想要的,但请记住,他们没有得到广泛的支持在IE浏览器(我认为他们将在IE10)。
Web Workers上的一些资源:
- 使用Web工作者
- 维基百科的文章在networking工作者
- WHATWG:networking工作者
以下是在没有web worker的情况下完成multithreading的一些资源。 需要注意的是,这不是“真正的”multithreading:
- 在Javascript中的multithreading (标题是有点误导,这不是真正的multithreading)
- 为什么Javascript不支持multithreading?
- 有什么方法可以在Javascript中执行multithreading?
- 使用IFRAME模拟multithreading (我不确定这个方法是多么可行;它可能比它的价值更麻烦,收益递减规律可能适用)。
我会build议看看暂停,但唉。 John Resig(jQuery的)这篇文章解释了一些关于JavaScript如何处理单线程的内容。 http://ejohn.org/blog/how-javascript-timers-work/
本文还解释说:“在JavaScript中asynchronous执行函数时需要记住的一件事情是,在函数调用完成之前,页面中的所有其他JavaScript执行都将停止,这就是所有当前浏览器都执行JavaScript的原因,并且如果执行JavaScript你试图同时调用太多的东西,一个长时间运行的函数实际上会为用户“locking”浏览器,同样的函数调用也是如此。
所有这一切,可能你可以模拟一个asynchronous函数调用,通过打破你正在做的一个更小的块和使用setTimeout()的任何循环。
比如这个function:
// Sync (function() { for(var x = 0; x < 100000; ++x) {console.log(x)} })() // ASync var x = 0; setTimeout(function() { console.log(x++); if(x < 100000) setTimeout(arguments.callee, 1); } ,1)
你可能想要networking工作者!
编辑:我很惊讶有多less人跳到“不可能”,所以我会详细说明。 Web Workers是HTML 5规范的一部分 。 它们允许你产生线程来在后台运行脚本而不会阻塞UI。 他们必须是外部的js文件,被调用
var worker = new Worker('my_task.js');
并通过事件传达。