【问题标题】:Promisify child process communicationPromisify 子进程通信
【发布时间】:2018-01-25 13:25:27
【问题描述】:

是否可以承诺两个进程之间的通信?

比如,发送一条消息,然后等到收到响应,然后做某事。

我已经编写了代码,但我不知道如何解决与已发送消息相关的承诺,因为响应消息是在不同的函数中接收的,超出了承诺范围:|

var worker, job_id, promises = [];

worker = child_process.fork(__dirname + '/w.js');
worker.on('message', (message) => {
  let job_id = message.job_id;
  // how to resolve promises[job_id] ??
});

function send(data){
  job_id++;
  data.job_id = job_id;
  worker.send(data);

  var promise = new Promise((resolve, reject) => {
    // how to resolve this in the message handler?
  });

  promises[job_id] = promise;
}

这个函数应该像

send(data).then((response_message) => {
  console.log(response_message);
});

【问题讨论】:

    标签: javascript node.js electron es6-promise child-process


    【解决方案1】:

    不要存储承诺,存储 resolve 函数:

    const worker = child_process.fork(__dirname + '/w.js');
    const jobs = new Map();
    let job_id;
    
    worker.on('message', message => {
      const job_id = message.job_id;
      const resolve = jobs.get(job_id);
      jobs.delete(job_id);
      resolve(message);
    });
    
    function send(data){
      data.job_id = job_id++;
      worker.send(data);
      return new Promise(resolve => {
        jobs.set(job_id, resolve);
      });
    }
    

    【讨论】:

      【解决方案2】:

      对 Workers 使用 Promise 是一个非常好的主意,但我很难理解您的需求。您可以将job_id 作为消息对象的属性发送/接收到每个作业的工作人员,这具有巨大的优势。这大大简化了任务。只需提前将您的job_id 附加到您的data 对象上,然后按照以下方式操作即可;

      function send(worker, data){ // data already has a job_id property
        worker.send(data);
        return new Promise((v,x) => worker.onmessage(v), worker.onmessageerror(x));
      }
      var data = {data: "someData", job_id: 1};
      send(myWorker, data)
      .then(m => doSomethingWith(m.job_id, m.data))
      

      即使您没有机会向/从 Workers 发送和接收 job_id,您也可以通过将它们放在一个数组中并通过 Promise.all() 触发它们来跟踪承诺。这对于分散在多个工人身上的分段工作非常有益。

      function send(worker, data){ // data has no job_id property
        worker.send(data);
        return new Promise((v,x) => worker.onmessage(v), worker.onmessageerror(x));
      }
      var segmentedJobs = [job0, job1, job2],
          jobPromises   = segmentedJobs.map((j,i) => Promise.all([send(j),i]));
      Promise.all(jobPromises)
             .then(rs => rs.map(([data,id]) => doSomethingWith(data,id)));
      

      然而,大多数情况下,分段作业的结果是需要处理相关的数据。在这种情况下,您可以只减少或扫描 promises 数组,而无需考虑任何作业 ID。

      【讨论】:

        猜你喜欢
        • 2014-05-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-07
        • 2011-01-09
        • 1970-01-01
        • 1970-01-01
        • 2018-09-16
        相关资源
        最近更新 更多