如何用javascript编写简单的异步函数
我想调用一个javascript函数,它需要很长时间(5秒)才能完成,而不会冻结客户端的浏览器。他们单击按钮开始操作,然后在操作完成时收到通知。目前我写了一些类似的东西如何用javascript编写简单的异步函数,javascript,asynchronous,Javascript,Asynchronous,我想调用一个javascript函数,它需要很长时间(5秒)才能完成,而不会冻结客户端的浏览器。他们单击按钮开始操作,然后在操作完成时收到通知。目前我写了一些类似的东西 $(document).ready(function(){ $('#tokenbutton').click(function(){ // IMMEDIATE EFFECT $('#tokenbutton').attr("disabled",true).val("Computing..."
$(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);
});
});
及
但当我运行浏览器时,它会冻结我的浏览器。如何更改它,使其不会冻结我的浏览器?用例
创建一个将数据返回回调的非Ajax独立进程
解决方案
要求
浏览器必须:
- 支持HTML5
- 支持网络工作者
postMessage( //data )
代码
没有真正的异步是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
函数doSomething(){
对于(变量x=0;x<10000;x++){
//做点什么
}
}
//这样做可能会花费很长时间并锁定浏览器
分解代码
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.
var总计=0;
设置超时(剂量测量,4);
函数doSomething(){
对于(总计=总计;总计+100<100;总计++){
//做点什么
}
如果(总数<10000){
设置超时(剂量测量,4);
}
}
//这样做可以阻止浏览器冻结,但不会节省任何时间。
有几件事,,
我在setTimout中加了一个4毫秒的时间,因为这实际上是js将要除去的最低值,即使你加1,它默认为4
我使用了setTimeout模式而不是setInterval来防止下一个间隔在前一个on结束之前运行
最后,这种模式并不适用于所有情况。它最适合循环和基于序列的操作
希望有帮助我们在谈论什么样的“昂贵手术”?在一台普通的现代计算机上,5秒的处理器时间是一个很大的处理过程。很确定你不能在浏览器中完成这项工作,因为只有一个JS线程。在过去,我已经把它分块,并且有一个计时器启动,这样我就可以继续下一块了。具有讽刺意味的是,这是一个穷人的线程。@Bart对网络工作者的支持似乎还可以,但并不令人惊讶。您可能会错过15%的浏览器。只有WebWorkers才能在浏览器中异步执行JavaScript。但正如David Ehrmann所说,异步性并不是防止浏览器冻结的必要条件。这不应该是
typeof Worker==“function”
?我想在分解的版本中需要一个额外的计数器变量。你可能是对的,我从头开始就写了它,更多的是为了展示设计模式,而不是其他任何东西,因为OP确实给出了他的doExpensiveOperation()实际做了什么的细节
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.