当作为类的方法调用时,如何多次运行单个方法?
起初我尝试使用cluster
模块,但我意识到它只是从一开始就重新运行整个进程,理所当然。
我怎样才能实现下面列出的内容?
我想要一个类的方法来生成 n 进程,并且当并行任务完成时,我可以解析该方法返回的promise。
以下代码的问题是,调用cluster.fork()
会分叉index.js
进程。
index.js
const Person = require('./Person.js');
var Mary = new Person('Mary');
Mary.run(5).then(() => {...});
console.log('I should only run once, but I am called 5 times too many');
Person.js
const cluster = require('cluster');
class Person{
run(distance){
var completed = 0;
return new Promise((resolve, reject) => {
for(var i = 0; i < distance; i++) {
// run a separate process for each
cluster.fork().send(i).on('message', message => {
if (message === 'completed') { ++completed; }
if (completed === distance) { resolve(); }
});
}
});
}
}
答案 0 :(得分:1)
我认为简短的答案是不可能的。情况更糟 - 这与js
无关。对于特定问题中的多(处理或线程),您基本上需要每个线程中对象的副本,因为它需要(可能)访问字段 - 在这种情况下,您需要在每个线程中初始化它或共享内存。最后一个我不认为是在cluster
中提供的,并且在每个用例中都不是其他语言中的琐碎。
如果计算独立于我建议您提取的人,并使用通常的(index.js
):
if(cluster.isWorker) {
//Use the i for calculation
} else {
//Create Person, then fork children in for loop
}
然后您收集结果并根据需要更改Person。您将复制index.js
,但这是标准的,您只运行所需的。
问题是结果是否依赖于Person。如果这些对于所有i
都是常量,您仍然可以将它们独立发送到您的叉子。否则你拥有的是唯一的分叉方式。一般来说,cluster
中的分叉不是用于方法,而是用于应用程序本身,这是标准的分叉行为。
另一种解决方案
根据您的评论,我建议您在同一档案中结帐child_process.execFile或child_process.exec
。
通过这种方式,您可以动态生成完全独立的进程。现在,您可以拨打cluster.fork
而不是致电execFile
。您可以使用退出代码或stdout作为返回值(stderr等)。承诺现在替换为:
var results = []
for(var i = 0; i < distance; i++) {
// run a separate process for each
results.push(child_process.execFile().child.execFile('node', 'mymethod.js`,i]));
}
//... catch the exit event from all results or return a callback using results.
内部mymethod.js
让您的代码获取i
并在退出代码或stdout中返回您想要的内容,这两个属性都是返回的child_process
。由于您正在等待异步呼叫,因此这有点不合情理node.js
- 但您的要求是非标准的。由于我不确定你如何使用它,或许返回一个带数组的回调是一个更好的主意。