Javascript 为什么不是所有的网络工作者都用postMessage发回数据?

Javascript 为什么不是所有的网络工作者都用postMessage发回数据?,javascript,web-worker,Javascript,Web Worker,我在一个循环中调用4个不同web工作者的postMessage。我试着为每个人制作不同的文件,并为每个人使用相同的文件,得到相同的结果。我的主线程webworker onmessage函数只被调用一次。我需要我的其他三个网络工作者返回他们的区块 html worker.js self.onmessage = (e) => { console.log('worker file', e.data); let marr; if (e.data[0]) { marr = new Array

我在一个循环中调用4个不同web工作者的postMessage。我试着为每个人制作不同的文件,并为每个人使用相同的文件,得到相同的结果。我的主线程webworker onmessage函数只被调用一次。我需要我的其他三个网络工作者返回他们的区块

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!');
    }
}

Lol休息了一会儿,回来了,再次用函数vs箭头表达式进行切换,然后终于看到,在分配web workers的onmessage的循环中,我用常数0而不是I对数组进行了索引太棒了

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!');
    }
}