const Worker = require("./WorkerClass");
module.exports = (input) => new Promise((resolve) => {
let N = 1; // count of threads
const tempList = [];
try {
while (true) {
tempList.push(new Worker("./worker"));
}
} catch (e) {
N = tempList.length;
tempList.forEach(w => {
w.delete();
})
}
const doOneWork = (element) => {
return new Promise((res, rej) => {
try {
const worker = new Worker("./worker"); // создаём подпрограмму, которая займёт один из потоков
worker.onMessage = ({data}) => { // подписываемся на его сообщение
worker.delete();
res(data);
};
worker.postMessage(element); // отправляем сообщение подпрограмме, чтобы он начал работу
} catch (e) {
// свободных потоков нет, ждём освобождения и создаём инстанс подпрограммы повторно
rej(e);
}
})
}
const doSeveralWork = async (arr) => {
// return new Promise((res, rej) => {
// try {
// const worker = new Worker("./worker"); // создаём подпрограмму, которая займёт один из потоков
// const resultList = [];
// worker.onMessage = ({data}) => { // подписываемся на его сообщение
// // тут работа выполнена, используем data и освобождаем процесс
// resultList.push(data);
// if (resultList.length === arr.length) {
// worker.delete();
// res(resultList);
// }
// };
// arr.forEach(text => {
// worker.postMessage(text); // отправляем сообщение подпрограмме, чтобы он начал работу
// });
// } catch (e) {
// // свободных потоков нет, ждём освобождения и создаём инстанс подпрограммы повторно
// rej(e);
// }
// })
const resultList = [];
for (const el of arr) {
resultList.push(await doOneWork(el));
}
return resultList;
};
if (input.length === 0) {
resolve("0");
return;
}
let process = async () => {
do {
const chunkSize = input.length / N;
const chunkList = [];
for (let i = 0; i < input.length; i += chunkSize) {
chunkList.push(input.slice(i, i + chunkSize));
}
const promiseList = chunkList.map(ch => doSeveralWork(ch));
const resList = await Promise.all(promiseList);
// [[1, 2], [2, 3]] -> [1, 2, 2, 3]
const resFlattened = Array.prototype.concat.apply([], resList);
input = [];
for (let i = 0; i < resFlattened.length; i += 2) {
if (i === resFlattened.length - 1) {
input.push(resFlattened[i] + resFlattened[i]);
} else {
input.push(resFlattened[i] + resFlattened[i + 1]);
}
}
} while (input.length !== 1);
return doOneWork(input);
}
process().then(resolve) ///
});