与Promises并行读取数字数组

时间:2018-08-23 12:21:54

标签: javascript algorithm es6-promise

我有一个数字数组,我想与一些工人(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);
});

0 个答案:

没有答案