JS:网络工作者不能工作

时间:2016-11-04 10:28:51

标签: javascript html html5

我正在编写代码,但看起来不能正常工作,这里有什么问题:

HTML

<div>
    <button onclick="startWorkerp3()">Start Worker</button> 
    <button onclick="stopWorkerp3()">Stop Worker</button>
    <img id="p_3" src="PROBLEM3.png" style="display: none;">
    <output id="p3"></output>
</div>

JS:

<script>
        var w;

        function startWorkerp3() {
            if(typeof(Worker) !== "undefined") {
                if(typeof(w) == "undefined") {
                    w = new Worker("p3.js");
                }
                w.onmessage = function(event) {
                    document.getElementById("p3").innerHTML = event.data;
                };
            } else {
                document.getElementById("p3").innerHTML = "Sorry! No Web Worker support.";
            }
        }

        function stopWorkerp3() { 
            w.terminate();
            w = undefined;
        }

        function isPrime(value) {
            for(var i = 2; i < value; i++) {
                if(value % i === 0) {
                    return false;
                }
            }
            return value > 1;
        }
</script>

p3.js

function problem3(){
    var img = document.getElementById('p_3');
    img.style.display = img.style.display === 'block' ? 'none' : 'block';
    var number=1+e9;
    for(var i=2;i<number;i++){
        if(isPrime(i) && number%i==0)
            var maxPrime = i;
    }
    postMessage(maxPrime);
}

输出无效:

enter image description here

我加载p551并且它正常工作,现在我试图在p3.js上使用WebWorker在没有浏览器错误的情况下使用它,询问你是否要等待或者终止它。 但我认为代码是用正确的语法编写的,那么错误是什么?

1 个答案:

答案 0 :(得分:1)

由于Web worker无法与DOM交互,因此这里的想法是处理Web worker中的所有计算(即p3.js),并且应该在另一侧处理显示更新,因为它们已被锁定在UI线程中,无论我们做什么(反正afaik)。

isPrime可能会在p3.js中重新定位,因为window在工作人员的上下文中不可用。

您的代码中有一些内容已被破坏。另外你可能不想用1e9这么高的值来测试用非优化算法找到素数,它可能看起来像是无关紧要的事情但是当你想测试某些东西有效时,我建议不要对“旁观者”过于疯狂:D

首先,让我们摆脱工人方面的DOM api调用。 (请注意,我已将1+e9替换为+1e9

function problem3(){
    var number = +1e9;
    for(var i=2;i<number;i++){
        if(isPrime(i) && number%i==0)
            var maxPrime = i;
    }
    postMessage(maxPrime);
}

现在,由于p3.js是不同线程中的不同文件,因此您无法访问主脚本的任何内存。这意味着isPrime在工作人员的上下文中不可用。希望这有一个直接的解决方案,因为您只需将isPrime函数移动到p3.js。

您正在使用onclick="startWorkerp3()"附加您的用户控件。通常建议用户addEventListener,在这种特殊情况下,由于onclick的上下文处理,您的工作人员永远不会启动

作为替代方案,例如它可能看起来像这样

<button id="start">Start Worker</button>

在主脚本文件中,我们需要重新定位从worker中删除的代码。根据我的理解,您希望在计算结束时切换图像可见性。

document.querySelector('#start').addEventListener('click', function () {
    document.getElementById('p_3').style.display = 'none';
    startWorkerp3();
});

当工人完成计算时

w.onmessage = function(event) {
    document.getElementById("p3").innerHTML = event.data;
    document.getElementById("p_3").style.display = 'block';
};

最后这里是它的样子(我总结一下,这样你就可以轻松复制/粘贴并测试它)。你可能会发现我做的一些小调整,其中一些可以被忽略,反正它解释每件小事都太长了。

<强> HTML

<div>
    <button id="start">Start Worker</button>
    <button id="stop">Stop Worker</button>
    <img id="p_3" src="PROBLEM3.png" alt="PROBLEM3.png" style="display: none;">
    <output id="p3"></output>
</div>

<强> JS

    var w;

    document.querySelector('#start').addEventListener('click', function () {

        var img = document.getElementById('p_3');
        img.style.display = 'none';

        startWorkerp3();
    });

    document.querySelector('#stop').addEventListener('click', function () {
        if (w) {
            stopWorkerp3();
        }
    });


    function startWorkerp3() {
        if(typeof(Worker) !== "undefined") {
            if(typeof(w) == "undefined") {
                w = new Worker("p3.js");
            }
            w.onmessage = function(event) {
                document.getElementById("p3").innerHTML = event.data;
                document.getElementById('p_3').style.display = 'block';
            };
        } else {
            document.getElementById("p3").innerHTML = "Sorry! No Web Worker support.";
        }

        w.postMessage('start');
    }


    function stopWorkerp3() { 
        w.terminate();
        w = undefined;
    }

<强> p3.js

onmessage = function (evt) {
    postMessage(problem3());
};


function problem3() {
    var number=100000;
    for(var i=2;i<number;i++){
        if(number%i==0 && isPrime(i))
            var maxPrime = i;
    }

    return maxPrime;
}


function isPrime(value) {
    for(var i = 2; i < value; i++) {
        if(value % i === 0) {
            return false;
        }
    }
    return value > 1;
}