Nodejs批处理

时间:2016-09-19 02:47:32

标签: node.js batch-processing

一些概念性问题

我有15个(例如)需要处理的文件。但我不想一次处理一个。相反,我想开始处理其中的5个(任何5个顺序并不重要),并且只要处理这5个文件中的一个,就可以启动另一个文件。我们的想法是在处理所有文件之前同时处理最多5个文件。

尝试在Node中解决这个问题,但总的来说,我不知道如何实现这一点

3 个答案:

答案 0 :(得分:3)

此类处理的更准确名称可能是“有限并行执行”。 Mario Casciaro在他的书“Node.js设计模式”(第77页)中介绍了这一点。这种模式的一个用例是当你想控制一组可能导致过载的并行任务时。下面的例子来自他的书。

有限并行执行模式

function TaskQueue(concurrency) {
  this.concurrency = concurrency;
  this.running = 0;
  this.queue = [];
}

TaskQueue.prototype.pushTask = function(task, callback) {
  this.queue.push(task);
  this.next();
}

TaskQueue.prototype.next = function() {
  var self = this;
  while(self.running < self.concurrency && self.queue.length) {
    var task = self.queue.shift();
    task(function(err) {
      self.running--;
      self.next();
    });
    self.running++;
  }
}

答案 1 :(得分:2)

您可以通过以下代码执行您想要的操作,但我很困惑您为什么要这样做?

  function handle(file) {
    new Promise(function(resolve, reject) {
      doSomething(file, function(err) {
        if(err)
          reject(err);
        else
          resolve();
      });
    })
    .then(function() {
      handle(files.shift());
    });
  }

  var files = [1, 2, ....., 15];
  var max = 5;
  while(max--) {
    handle(files.shift());
  }

答案 2 :(得分:2)

这是一个模拟多个工作人员从中央工作队列中读取的小例子:https://jsfiddle.net/ctrlfrk/jsvyg69h/1/

// Fake "work" that is simply a task that takes as many milliseconds as its value.
const workQueue = [1000,4000,2000,4000,5000,3000,7000,1000,9000,9000,4000,2000,1000,3000,8000,2000,3000,7000,6000,30000];


const Worker = (name) => (channel) => {
  const history = [];
  const next = () => {
    const job = channel.getWork();
    if (!job) { // All done!
      console.log('Worker ' + name + ' completed');
      return;
    }
    history.push(job);
    console.log('Worker ' + name + ' grabbed new job:' + job +'. History is:', history);

    window.setTimeout(next, job); //job is just the milliseconds.
  };
  next();
}

const Channel = (queue) => {
  return { getWork: () => {
    return queue.pop();
  }};
};

let channel = Channel(workQueue);
let a = Worker('a')(channel);
let b = Worker('b')(channel);
let c = Worker('c')(channel);
let d = Worker('d')(channel);