如何循环Web工作者?

时间:2018-05-02 16:05:22

标签: javascript web-worker

我正在建立一个使用PHP,AJAX和Javascript的网站,用户可以帮助计算PI,这纯粹是为了学习目的而且我知道有更有效的方法来计算PI。

我需要选择一个随机位置然后查看它是否在一个圆圈中,因为我已创建此代码

var size = 500;

function calculate() {
    var Xpos = Math.floor(Math.random() * size);
    var Ypos = Math.floor(Math.random() * size);

    var dist = Math.hypot(Ypos-Xpos, size / 2 - size / 2);

    if (dist <= size / 2) postMessage(true);
    else postMessage(false);

    setTimeout("calculate()", 1);
}

calculate();

哪个效果很好,尽管它可能会更快,因为那里有一个不需要的超时(我认为它无论如何都没有),所以如果我只是删除它并仅用calculate();替换它来加速它我收到此错误

  

未捕获RangeError:超出最大调用堆栈大小

我如何解决这个问题,我希望让工作人员为每一个工作(或直到用户关闭页面)

编辑: 要清楚,我上面发布的代码有效!但是当我用setTimeout("calculate()", 1);

替换calculate();时,它就会停止工作

2 个答案:

答案 0 :(得分:1)

工作人员的优势在于它们允许您从主线程中移动繁重的处理。如果从代码中删除setTimeout,您仍然会向主线程发送大量处理,而不是用于计算PI,但仍然用于处理工作人员消息。

因此,我们的想法是在向主线程发送消息之前尽可能长时间地处理。例如,在您的应用程序中,您可以运行多次迭代并将结果发送到一条消息中:

const size = 500;

function calculate() {
    const iterations = 100000;
    while (true) { // you will probably want to have a condition to stop
      let inside = 0;
      for (let i = 0; i < iterations; i++) {
        var Xpos = Math.floor(Math.random() * size);
        var Ypos = Math.floor(Math.random() * size);

        var dist = Math.hypot(Ypos-Xpos, size / 2 - size / 2);

        if (dist <= size / 2) {
          inside++;
        }
      }
      postMessage({iterations, inside});
    }
}

calculate();

答案 1 :(得分:0)

setTimeout([func],delay)等待定义的延迟量,然后调用函数一次并停止,因此立即调用它会溢出堆栈,因为没有间隙可以释放资源。

无限循环将冻结页面

并且由于您希望在页面处于活动状态时运行,因此您需要使用setInterval,它会经常(您的dely)继续调用该函数,直到您关闭页面。

var size = 500;
setInterval(function() {
    var Xpos = Math.floor(Math.random() * size);
    var Ypos = Math.floor(Math.random() * size);

    var dist = Math.hypot(Ypos-Xpos, size / 2 - size / 2);

    if (dist <= size / 2) postMessage(true);
    else postMessage(false);

}, 1);