Node.js - 将N个函数与一个同步

时间:2014-07-31 08:02:08

标签: node.js synchronization

假设这样的伪代码:

function get_data_and_reply(response) {
  // process 1: 
  db_connect.query(..., function(...){
    // get A from db 
  });

  // process 2:
  db_connect.query(..., function(...){
    // get B from db 
  });

  // process 3: aggregate A + B and reply
}

一种可能的解决方案是使用回调(hell;)),就像这样

function get_data_and_reply(response) {
  // process 1: 
  db_connect.query(..., function(...){
    // get A from db 

    if (err) {} else {
      // process 2:
      db_connect.query(..., function(...){
        // get B from db 

        if (err) {} else {
          // process 3: aggregate A + B and reply
        }
      });
    }
  });
}

但我想保持与进程1和2的并行性(可能需要时间,如果它们并行则会更好),然后与进程3“序列化”。

如何将N个步骤(并行)与一个步骤同步?

我考虑过玩变量和循环,直到另一个方法结束,但听起来有点错综复杂,不是吗?

function get_data_and_reply(response) {
  // process 1: 
  db_connect.query(..., function(...){
    // get A from db 
  });

  // process 2:
  db_connect.query(..., function(...){
    // get B from db 
  });

  // process 3: aggregate A + B and reply
  while (A_is_not_ready && B_is_not_ready) {}
}

2 个答案:

答案 0 :(得分:2)

如果您不介意使用库,async是一个很棒的库。你可以这样使用它:

function get_data_and_reply(response) {
  async.parallel({
    A: function (next) {
      // process 1: 
      db_connect.query(..., next); // Assuming the db returns the result like (err, result)
    },
    B: function (next) {
      // process 2:
      db_connect.query(..., next);
    }
  }, function (err, results) {
    // This is called when both parallel functions are done. Use results.A and .B
    // process 3: aggregate A + B and reply
  })
}

在没有任何助手的情况下做这件事也很简单,不要太漂亮:

function get_data_and_reply(response) {
  var aResult, bResult;
  // process 1: 
  db_connect.query(..., function(..., result){
    // get A from db 
    aResult = result;
    done();
  });

  // process 2:
  db_connect.query(..., function(..., result){
    // get B from db 
    bResult = result;
    done();
  });

  function done() {
    if(aResult && bResult) {
      // process 3: aggregate A + B and reply
    }
  }
}

如果您使用后一种方法,请不要忘记处理错误。

答案 1 :(得分:0)