我想调用一个需要很长时间(5秒)才能完成的javascript函数,而不会冻结我客户端的浏览器。他们点击按钮开始操作,然后在完成时通知他们。目前我写了像
这样的东西$(document).ready(function(){
$('#tokenbutton').click(function(){
// IMMEDIATE EFFECT
$('#tokenbutton').attr("disabled",true).val("Computing...");
var callback = function(resultsFromExpensiveOperation){
// CALLBACK EFFECTS
$('#tokenbutton').val("Token computed");
$('#submitbutton').attr("disabled",false);
// ...
};
// FREEZES BROWSER
doExpensiveOperation(callback);
});
});
和
doExpensiveOperation = function(callback){
// ...
//var results = ...
callback(results);
};
但是当我运行它时会冻结我的浏览器。如何更改它以便不冻结我的浏览器?
答案 0 :(得分:1)
创建一个非Ajax单独进程,将数据返回给回调。
浏览器必须:
使用逻辑为单独的线程进程创建单独的文件。该文件必须包含以下代码:
postMessage( //data )
if(typeof(Worker) === "function") {
var worker = new Worker(//uri to js file);
worker.onmessage = function(event){
// my call back.
};
}
答案 1 :(得分:1)
没有真正的异步是javascript,因此没有多线程或类似的东西。在某些情况下,有一种方法可以使长时间运行的功能不冻结浏览器。
您可以使用setInterval或setTimeout函数一次执行长时间运行任务的一小部分,因此每个位只需要几分之一秒,然后ui再次响应几分之一秒直到下一位运行。这在功能上使ui保持响应,并且不会在代码处理上增加太多时间(如果有的话)。例如。
长时间运行的代码
function doSomething(){
for(var x = 0; x < 10000; x++){
// do something
}
}
// doing it like this could take forever and lock up the browser
分解代码
var total = 0;
setTimeout(doSomething, 4);
function doSomething(){
for(total = total; total + 100 < 100; total++){
// do something
}
if(total < 10000){
setTimeout(doSomething, 4);
}
}
// doing it like this stops the browser from freezing but does not save any time.
一些事情, 我把4毫秒的时间放入setTimout,因为这实际上是js的最低值,除非你将1的默认设置为4。
我使用了setTimeout模式而不是setInterval来防止下一个间隔在完成上一个间隔之前运行。
最后,这种模式并不适用于所有事情。它最适合循环和基于序列的操作。
希望有所帮助