Javascript 如何从字符串创建子进程

Javascript 如何从字符串创建子进程,javascript,node.js,Javascript,Node.js,在浏览器中,我们可以从javascript字符串创建Worker,如下所示: var blob = new Blob([sourceString]); var url = window.URL.createObjectURL(blob); var worker = new Worker(url); 是否有任何方法可以使用节点的?我有一个JavaScript文件,我想创建动态编码的worker 源字符串是在运行时动态创建的字符串。 我找到的最接近的答案是,但它需要一个单独的文件。如果您希望一个文

在浏览器中,我们可以从javascript字符串创建Worker,如下所示:

var blob = new Blob([sourceString]);
var url = window.URL.createObjectURL(blob);
var worker = new Worker(url);
是否有任何方法可以使用节点的?我有一个JavaScript文件,我想创建动态编码的worker

源字符串是在运行时动态创建的字符串。


我找到的最接近的答案是,但它需要一个单独的文件。

如果您希望一个文件来启动不同的进程,那么创建集群可能是一个解决方案。下面是一个非常好的教程:

基本上,节点随本机集群模块一起提供

var cluster = require('cluster');
您可以通过cluster.isMaster判断进程是主进程还是辅助进程。如果进程是主进程,则可以通过执行cluster.fork()来加速工作进程

if(cluster.isMaster){
对于(变量i=0;i
希望这有帮助


对于子进程,您可以child\u process.fork(modulePath[,args][,options])运行其他模块并传入参数。该模块可以根据参数做不同的事情,因此它是动态的。。。似乎您只需要基于输入的动态行为,如果您可以将代码放入不同的文件中,子进程就可以做到这一点。如果您只能拥有一个,请尝试群集解决方案。

如果我理解正确,我昨天创建了一个解决方案

它的目的不是从字符串而是从实际函数创建worker,因为实际函数代码必须通过think消息传递,所以它们被字符串化以在worker内部重建(think eval())

这是通过代码实现的:

var source = fn.toString();
…因此,拥有这个字符串原型还有一个
.toString()
方法,将函数作为字符串传递也必须有效(事实上有效。我刚刚测试了它)

它可能不是您想要的:如果您需要向工作人员传递消息,则此模块不适合您。但您可以查看并修改它以满足您的需要

另一方面,如果您只想在后台执行某个函数并获得结果,那么这比处理辅助管道要简单得多,因为您可以将参数传递给该函数并获得结果,就像一个简单的函数调用一样

示例:

// Reauires funwork (`npm install --save funwork`)

var funwork = require("funwork");
var workerfn = funwork(function_src_string); // or actual function.
它的缺点是必须通过
eval()
对函数进行求值,但是,在您的情况下,(具有字符串源代码),我认为这无论如何都是必须的

编辑:这里是funwork的一个修改版本,以达到我们在评论中讨论的目的:

var Worker = require('webworker-threads').Worker;
var Deasync = require('deasync');

function strWorker(fn){

    var source = fn.toString();

    return function() {

        var done = false;
        var args = Array.prototype.slice.call(arguments);
        var error;

        // Create worker://{{{
        var worker = new Worker(function(){
            var fn;
            var me = this;

            // Wait for function source and arguments:
            me.onmessage = function(event) {
                switch (event.data.oper) {
                    case "src":
                        // "Compile" function thougt source evaluation.
                        try {
                            eval ("fn = " + event.data.msg + ";");
                            postMessage(['ready']);
                        } catch (e) {
                            postMessage(['error', "Error trying to evaluate function source"]);
                        };
                        break;
                    case "args":
                        // Call the function with given arguments and reset the rest of worker stuff.
                        try {
                            // Reset worker (inside) event handler:
                            delete me.onmessage;

                            // Notify that worker is ready:
                            postMessage(["ok"]);

                            // Start function execution:
                            fn.apply(me, event.data.msg);

                        } catch (e) {
                            postMessage(['error', e]);
                        };
                        break;
                };
            };
        });//}}}

        // Event handling://{{{
        worker.onmessage = function(event) {
            switch (event.data[0]) {
                case 'error':
                    worker.postMessage({oper: "end"});
                    done = true;
                    error = event.data[1];
                    break;
                case 'ready':
                    worker.postMessage({oper: "args", msg: args});
                    break;
                case 'ok':
                    done = true;
                    break;
            };
        };//}}}

        // Send function source to worker:
        worker.postMessage({oper: "src", msg: source});

        // Wait (without blocking) until worker executed passed function:
        Deasync.loopWhile(function(){return !done;});

        if (error) throw error;

        // Reset worker (outside) event handler:
        delete worker.onmessage;

        return worker;
    };

};

module.exports = strWorker;
我保留了向函数传递参数的功能,因为它已经实现了,如果不需要传递任何东西,就可以不使用它

用法相同,唯一的区别是生成的函数返回一个正在运行的worker,而不是函数返回值


在函数(以字符串形式传入)执行和工作者返回之前,分别删除已使用的事件处理程序(工作者内部和外部),以避免任何副作用,传入函数的执行上下文(“this”)也设置为实际工作者“父”函数

伟大的模块!遗憾的是,我不能使用它,因为我需要向工作者传递消息和从工作者传递消息。但您可以使用相同的方法从字符串源创建工作者。请看代码:它非常简单并且是自动解释的(我想也是希望如此)。事实上,我认为您只需要删除不需要的代码,而不是返回函数包装器,而是返回worker本身。啊哈!我不知道有一个叫做webworker线程的库。这帮我找到了解决办法,我也没有。Npm是你的朋友!!;-)你能用一个临时文件而不是让它变得超级复杂吗?这不是我想要的,但还是很有趣的。
var Worker = require('webworker-threads').Worker;
var Deasync = require('deasync');

function strWorker(fn){

    var source = fn.toString();

    return function() {

        var done = false;
        var args = Array.prototype.slice.call(arguments);
        var error;

        // Create worker://{{{
        var worker = new Worker(function(){
            var fn;
            var me = this;

            // Wait for function source and arguments:
            me.onmessage = function(event) {
                switch (event.data.oper) {
                    case "src":
                        // "Compile" function thougt source evaluation.
                        try {
                            eval ("fn = " + event.data.msg + ";");
                            postMessage(['ready']);
                        } catch (e) {
                            postMessage(['error', "Error trying to evaluate function source"]);
                        };
                        break;
                    case "args":
                        // Call the function with given arguments and reset the rest of worker stuff.
                        try {
                            // Reset worker (inside) event handler:
                            delete me.onmessage;

                            // Notify that worker is ready:
                            postMessage(["ok"]);

                            // Start function execution:
                            fn.apply(me, event.data.msg);

                        } catch (e) {
                            postMessage(['error', e]);
                        };
                        break;
                };
            };
        });//}}}

        // Event handling://{{{
        worker.onmessage = function(event) {
            switch (event.data[0]) {
                case 'error':
                    worker.postMessage({oper: "end"});
                    done = true;
                    error = event.data[1];
                    break;
                case 'ready':
                    worker.postMessage({oper: "args", msg: args});
                    break;
                case 'ok':
                    done = true;
                    break;
            };
        };//}}}

        // Send function source to worker:
        worker.postMessage({oper: "src", msg: source});

        // Wait (without blocking) until worker executed passed function:
        Deasync.loopWhile(function(){return !done;});

        if (error) throw error;

        // Reset worker (outside) event handler:
        delete worker.onmessage;

        return worker;
    };

};

module.exports = strWorker;