我有一个数字数组,我想与一些工人(Promises)并行阅读它们,允许最多同时工作的工人。
我想在所有工人都完成工作后,通过Promise获得一个数字数组的结果。 读取数字的顺序并不重要。
我已经写了一些接近解决方案的代码,但是工作人员被保证会在创建后立即开始工作,(如您所打印的“活动工作人员”信息所示,其中包含比maxWorkers更多的项目) )。因此,我无法控制实际要运行的数量,这是我想要的。 我真正想要的是在“活动工人”信息中看到最多maxWorkers。
一个工人最多可以创建一个maxWorkersToCreate工人,并且工作的工人总数可以与maxWorkers一样高。
这只是一个玩具示例,我要做的实际工作是并行阅读一些Web资源。这就是我想到Promises的原因,这就是为什么代码中有一个setTimeout(用于模拟异步操作)的原因。
也接受图书馆建议。
Object.defineProperty(Array.prototype, 'flat', {
value: function(depth = 1) {
return this.reduce(function(flat, toFlatten) {
return flat.concat((Array.isArray(toFlatten) && (depth - 1)) ? toFlatten.flat(depth - 1) : toFlatten);
}, []);
}
});
const workerManager = new class WorkerManager {
constructor() {
this.workers = [];
}
showWorkers() {
let w = this.workers.filter(function(n){ return n != undefined });
console.log("Active workers:", w);
}
setWorker(name) {
this.workers[name] = name;
}
removeWorker(name) {
delete this.workers[name];
}
}
const MAX = 10;
var numbers = [];
for (var i = 0; i < MAX; i++) {
numbers.push(i);
}
// last position being read from workers
let maxPositionQueued = 0;
// max number of workers working
const maxWorkers = 3;
// max workers a worker can create
const maxWorkersToCreate = 4;
// current number of workers working
let currentWorkers = 0;
function readAll(positionToRead) {
if (currentWorkers > maxWorkers) {
// Rescheduling worker
return new Promise(function(resolve) {
setTimeout(function() {
resolve(readAll(positionToRead));
}, Math.random() * 10 + 10);
});
}
function readNumber() {
return new Promise(function(resolve) {
workerManager.setWorker(positionToRead);
workerManager.showWorkers();
console.log("Reading pos:", positionToRead);
setTimeout(function() {
let result = numbers[positionToRead];
workerManager.removeWorker(positionToRead);
resolve(result);
}, Math.random() * 500 + 1000);
});
}
currentWorkers++;
return readNumber().then(function(response) {
let workers = [];
while (workers.length < maxWorkersToCreate &&
maxPositionQueued < MAX - 1) {
/*
* here I'd like to queue a worker and not start it
* immediately
*/
workers.push(readAll(++maxPositionQueued));
}
currentWorkers--;
return Promise.all([
response,
workers
].flat()).then(function(responses) {
return responses.flat();
});
}); // then reponse END
}
readAll(0).then(function(response) {
console.log("Numbers:", response);
});