Javascript 如何从字符串创建子进程
在浏览器中,我们可以从javascript字符串创建Worker,如下所示: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 源字符串是在运行时动态创建的字符串。 我找到的最接近的答案是,但它需要一个单独的文件。如果您希望一个文
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;