如何在javascript中编写简单的异步函数

时间:2014-07-07 17:17:06

标签: javascript asynchronous

我想调用一个需要很长时间(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);
};

但是当我运行它时会冻结我的浏览器。如何更改它以便不冻结我的浏览器?

2 个答案:

答案 0 :(得分:1)

使用案例

创建一个非Ajax单独进程,将数据返回给回调。

解决方案

要求

浏览器必须:

  • 支持HTML5
  • 支持Web Workers

结构

使用逻辑为单独的线程进程创建单独的文件。该文件必须包含以下代码:

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来防止下一个间隔在完成上一个间隔之前运行。

最后,这种模式并不适用于所有事情。它最适合循环和基于序列的操作。

希望有所帮助