为什么不让所有网络工作者都使用postMessage发回数据?

时间:2018-05-04 22:12:47

标签: javascript web-worker

我在循环中对4个不同的Web worker调用postMessage。我尝试为每个文件制作不同的文件,并为每个相同的结果使用相同的文件。我的主要线程webworker onmessage函数只被调用一次。我需要我的其他三名网络工作人员来归还他们的块!

HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">

<title>The HTML5 Herald</title>
<meta name="description" content="The HTML5 Herald">
<meta name="author" content="SitePoint">

<link rel="stylesheet" href="./index.css">
</head>

<body>
<input type="text" id='input'><div style="word-wrap: break-word;" id='output'></div>
<script src="./m1worker.js"></script>
<script src="./m2worker.js"></script>
<script src="./m3worker.js"></script>
<script src="./m4worker.js"></script>
<script src="./IntToRomanNumeral.js"></script>
</body>
</html>

worker.js

self.onmessage = (e) => {
console.log('worker file', e.data);
let marr;
if (e.data[0]) {
    marr = new Array(e.data[0]);
    for (let i = 0; i < e.data[0]; i++) {
        marr[i] = 'M';
    }
}
self.postMessage([marr.join(""), e.data[1]]);
self.close();
};

主线程

const THREADCOUNT = 4;
const goodmap = Array(THREADCOUNT);
const workernames = [];

const setupGoodMapAndNamesArr = () => {
   for (let i = 0; i < THREADCOUNT; i++) {
       goodmap[i] = false;
       workernames.push('./m'+(i+1)+'worker.js');
   }
}

const stalltillgood = (cb) => {
console.log('stalling');
const realgood = goodmap.every((thread) => {
    return thread;
});
if (realgood) {
    cb();
}
else {
    setTimeout(stalltillgood.bind(this, cb), 1000);
}
}

const workerReturn = (e) => {
    console.log(e.data);
    output.appendChild(document.createTextNode(e.data[0]));
    goodmap[e.data[1]] = true;            
}

const ITRN = (str) => {
    setupGoodMapAndNamesArr();
    const workers = [];
    for (let i = 0; i < THREADCOUNT; i++) {
        workers.push(new Worker(workernames[i]));
    }
    var cNode = output.cloneNode(false);
    output.parentNode.replaceChild(cNode ,output);

    console.time("Start!");
    if (/^\d+$/.test(str)) {
        //generate the intermediate (invalid - doesn't follow rule)
        let inputnum = +str;
        if (inputnum > 100000000000) {
            return 'YOU MIGHT NOT HAVE ENOUGH MEMORY FOR THAT!'
        }
        let romannumeral = [];

        let numM = Math.floor(inputnum / 1000);
    if (numM) {
        inputnum -= numM * 1000;
    }

    const numD = Math.floor(inputnum / 500);
    if (numD) {
        inputnum -= numD * 500;
    }

    const numC = Math.floor(inputnum / 100);
    if (numC) {
        inputnum -= numC * 100;
    }

    const numL = Math.floor(inputnum / 50);
    if (numL) {
        inputnum -= numL * 50;
    }

    const numX = Math.floor(inputnum / 10);
    if (numX) {
        inputnum -= numX * 10;
    }

    const numV = Math.floor(inputnum / 5);
    if (numV) {
        inputnum -= numV * 5;
    }

    console.time('Start pushing intermediate');
    console.time('PUSH MS!');
    if (numM >= 4) {
        const remain = numM % 4;
        numM = Math.floor(numM / 4);
        for (let i = 0; i < THREADCOUNT; i++) {
            workers[0].onmessage = workerReturn;
        }

        workers[0].postMessage([numM+remain, 0]);
        for (let i = 1; i < THREADCOUNT; i++) {
            workers[i].postMessage([numM, i]);
        }
    }
    else {
        for (let i = 0; i < THREADCOUNT; i++) {
            goodmap[i] = true;
        }
    }

    stalltillgood(() => {
        //appendChild the text chunks after =() and see
        console.log('we are good');
        console.timeEnd('PUSH MS!');

        for (let i = 0; i < numD; i++) {
            romannumeral.push('D');
        }

        for (let i = 0; i < numC; i++) {
            romannumeral.push('C');
        }

        for (let i = 0; i < numL; i++) {
            romannumeral.push('L');
        }

        for (let i = 0; i < numX; i++) {
            romannumeral.push('X');
        }

        for (let i = 0; i < numV; i++) {
            romannumeral.push('V');
        }

        for (let i = 0; i < inputnum; i++) {
            romannumeral.push('I');
        }
        console.timeEnd('Start pushing intermediate');

        //find invalid strings in the intermediate
        //generate an array of new str segments to be joined
        //replace the invalid strings with their valid forms
        const invalidtovalidmap = {
            I: 'IV',
            V: 'VX',
            X: 'XL',
            C: 'CD',
            D: 'DM',
        };

        const nextturtleupmap = {
            I: 'V',
            X: 'L',
            C: 'D',
        };

        const turtlingmap = {
            I: 'IX',
            C: 'CM',
            X: 'XC',
            C: 'CM',
        };

        let validromannumeral;
        let count = 0;
        let i;
        let m = romannumeral.indexOf('M');
        if (m !== -1) {
            let lastm = romannumeral.lastIndexOf('M');
            validromannumeral = romannumeral.slice(m, lastm);
            i = lastm++;
        }
        else {
            validromannumeral = [];
            i = 0;
        }
        let lastnumeral = romannumeral[i];
        validromannumeral.push(lastnumeral);
        i++;
        console.time('compilering');
        for (;i < romannumeral.length; i++) {
            if (lastnumeral === romannumeral[i]) {
                if (count === 2) {
                    count = 0;
                    validromannumeral.pop();
                    validromannumeral.pop();
                    validromannumeral.pop();
                    if (nextturtleupmap[romannumeral[i]]) {
                        if (validromannumeral[validromannumeral.length-1] === nextturtleupmap[romannumeral[i]]) {
                            validromannumeral.pop();
                            validromannumeral.push(turtlingmap[romannumeral[i]]);
                        }
                        else {
                            validromannumeral.push(invalidtovalidmap[romannumeral[i]]);
                        }                       
                    }
                    else {
                        validromannumeral.push(invalidtovalidmap[romannumeral[i]]);
                    }
                }
                else {
                    ++count;
                    validromannumeral.push(romannumeral[i]); 
                }                    
            }
            else {
                lastnumeral = romannumeral[i];
                count = 0;
                validromannumeral.push(romannumeral[i]);
            }
        }
        console.timeEnd('compilering');
        console.timeEnd('Start!');
        console.time('OUTPUT!');
             output.appendChild(document.createTextNode(validromannumeral.join("")));
    });
}
else {
    return 'INVALID INTEGER';
}
}

window.onload = () => {
    const input = document.getElementById('input');
    const output = document.getElementById('output');

    input.oninput = () => {
        ITRN(input.value);
        console.timeEnd('OUTPUT!');
    }
}

1 个答案:

答案 0 :(得分:1)

LOL,休息了一下,回来了,用功能vs箭头表达dicked,然后终于看到我在循环中分配我的网络工作者的onmessage我用一个常数0而不是i索引数组。 =)Yay线程GB的Ms!