2

我有这个代码使用一个inefficientProcess()消耗大量内存的代码:

我的目标是使用某种setTimeout(function(){...},0)技术,这样浏览器在执行代码时就不会卡住。

如何更改代码以使其与 setTimeout 一起使用?

function powerOfTwo(num) {
    inefficientProcess();
    if (num > 0) {
        return powerOfTwo(num-1)*2;
    } else {
        return 1;
    }
}

function inefficientProcess() {
    var sum;
    for (var i=0; i < 500000; i++) {
        sum+=10;
    }
}

powerOfTwo(1000);

我的目标当然是学习如何在执行繁重的计算时避免浏览器崩溃。

4

3 回答 3

3

Javascript 是单线程的,你所有的代码都是阻塞的。HTML5 中有一个新标准 WebWorkers API,它允许您将任务委托给不同的线程。然后,您可以传递一个回调函数来执行结果。

https://developer.mozilla.org/en-US/docs/DOM/Using_web_workers

简单的例子:

function powerOfTwo(num, callback) {
    var worker = new Worker('inneficient.js');
    worker.postMessage('runTask');
    worker.onmessage = function(event) {
        var num = event.data.result;
        var pow;
        if (num > 0) {
            pow = Multiply(num-1)*2;
        } else {
            pow = 1;
        }
        callback(pow);
    };    
}

powerOfTwo(1000, function(pow){
    console.log('the final result is ' + pow);
});

在 inneficient.js 你有类似的东西:

//inneficient.js

function inefficientProcess() {
    var sum;
    for (var i=0; i < 500000; i++) {
        sum+=10;
    }
     postMessage({ "result": sum});
}

inefficientProcess();
于 2013-02-25T18:20:44.717 回答
2

正如 Andre 的回答中提到的,有一个新的 HTML5 标准允许您在不同的线程上启动任务。否则,您可以调用时间为 0 的 setTimeout 以允许在调用 inefficientProcess 之前完成当前执行路径(可能还有一些要呈现的 UI 更改)。

但是无论您是否可以使用 HTML5,powerOfTwo 函数都必须更改为异步的 - 无论调用它的人都需要提供一个回调方法,该方法将在 (a) 通过 WebWorkers 启动的线程返回时调用,或者 (b) setTimeout 方法结束。

编辑添加示例:

function powerOfTwo(num, callback)
{
    setTimeout(function ()
    {
        inefficientProcess();
        if (num > 0)
            callback(Multiply(num-1)*2);
        else
            callback(1);
    }, 0);
}

function inefficientProcess() { ... }
于 2013-02-25T18:23:59.153 回答
0

HTML 元素允许您定义页面中的 JavaScript 代码应该何时开始执行。“async” 和 “defer” 属性在 9 月初被添加到 WebKit。Firefox 已经支持它们很长一段时间了。

在本站看到

于 2013-02-25T18:25:59.753 回答