Sar*_*els 41 javascript forms jquery asynchronous function
这看起来很傻,但我找不到如何使用不涉及某些服务器端请求的jQuery进行异步函数调用.我有一个缓慢的函数,遍历很多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;
});
Run Code Online (Sandbox Code Playgroud)
目前我提交表格并且指标未显示,浏览器冻结,然后slowFunctionCall完成.
编辑:我使用了Vivin的答案,特别是Sitepoint链接来获得以下解决方案:
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);
Run Code Online (Sandbox Code Playgroud)
这会显示和隐藏指示器,也不会冻结浏览器.您可以看到DOM元素在工作时被隐藏,这就是我想要的.
Viv*_*ath 30
Javascript在单个线程中运行,因此如果你的函数很慢,它将阻止其他所有内容.
UPDATE
这将做你想要的一些,但请记住,它们在IE 中不受广泛支持(我认为它们将在IE10中).
Web Worker上的一些资源:
以下是在没有Web工作者的情况下完成多线程的一些资源.重要的是要注意这不是"真正的"多线程:
我打算建议看一下超时但是唉.John Resig(jQuery)的这篇文章解释了JavaScript如何处理其单线程. http://ejohn.org/blog/how-javascript-timers-work/
本文还解释了:"在JavaScript中异步执行函数时要记住的一件事是,页面中的所有其他JavaScript执行都会暂停,直到函数调用完成.这就是所有当前浏览器执行JavaScript的方式,如果执行JavaScript会导致实际性能问题你试图同时异步调用太多东西.一个长时间运行的函数实际上会"锁定"用户的浏览器.同样的函数调用也是如此."
所有这一切,你可以通过将你正在做的循环分成一个较小的块并使用setTimeout()来自己模拟一个异步函数调用.
例如这个功能:
// 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)
Run Code Online (Sandbox Code Playgroud)
你可能想要网络工作者!
编辑:我很惊讶有多少人跳到"它不可能"所以我会详细说明.Web Workers是HTML 5规范的一部分.它们允许您生成线程以在后台运行脚本而不会阻止UI.它们必须是外部js文件,由它们调用
var worker = new Worker('my_task.js');
Run Code Online (Sandbox Code Playgroud)
并通过活动传达.
| 归档时间: |
|
| 查看次数: |
59219 次 |
| 最近记录: |