Untitled

 avatar
unknown
javascript
2 years ago
3.4 kB
3
Indexable
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) ///
});