Untitled

mail@pastecode.io avatar
unknown
javascript
2 years ago
2.4 kB
1
Indexable
const Worker = require("./WorkerClass");  
 
module.exports = (input) => new Promise((resolve) => {
  
  let N = 0; // count of threads
  const tempList = [];
  try {
    while (true) {
      tempList.push(new Worker("./worker"));    
    }
  } catch (e) {
    N = tempList.length;
    tempList.forEach(w => {
      w.delete();
    })
  }
  const doSeveralWork = (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);
      }  
    })
  };

  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 input;
  }
  
  process.then(resolve)
});