javascript异步任务处理

时间:2018-12-24 12:49:47

标签: javascript express asynchronous rabbitmq

我是Node开发的新手。 我在理解JS和Node的异步特性时遇到了麻烦。我正在构建一个微服务后端Web服务器,在网关服务中运行Express,该服务将REST请求转换为使用RabbitMQ异步消息传递(amqplib)模块发布的一系列消息,其他服务可以依次订阅,处理请求然后响应

我处理来自网关的异步请求的服务如下:

amqp.connect('amqp://172.17.0.2', function(err, conn) {
  console.log("connection created");
  conn.createChannel(function(err, ch) {
    console.log("channel created");
    var exchange = 'main';

    ch.assertExchange(exchange, 'topic', {durable: true});

    ch.assertQueue('', {exclusive: true}, function(err, q) {
      console.log(' [*] Waiting for logs. To exit press CTRL+C');

      ch.bindQueue(q.queue, exchange, "VENUE_TOPIC.PENDING_STATUS.*.*");

      ch.consume(q.queue, function(msg) { 
        console.log(" [x] %s:'%s'", msg.fields.routingKey, msg.content.toString());
        var pending_event = JSON.parse(msg.content.toString())
        console.log(pending_event.payload.id == 2)
        console.log(pending_event.payload.id)
        if (pending_event.payload.id == 1) { 
          var venue = getVenueByID(pending_event.payload.id);
          const approved_event = new Event("VENUE_TOPIC", "APPROVED_STATUS", false, "READ_METHOD", {"venue":venue});
          var key = approved_event.getMetaAsTopics();

          var msg = Buffer.from(JSON.stringify(approved_event.getEventAsJSON()));

          ch.assertExchange(exchange, 'topic', {durable: true});
          ch.publish(exchange, key, msg, {persistent: true});
          console.log(" [x] Sent '%s'", msg);        
        } else if (pending_event.payload.id == 2) {
          sleep(10000); //this function checks the OS's clock to count time in ms
          var venue = getVenueByID(pending_event.payload.id);
          const approved_event = new Event("VENUE_TOPIC", "APPROVED_STATUS", false, "READ_METHOD", {"venue":venue}); 
          var key = approved_event.getMetaAsTopics();

          var msg = Buffer.from(JSON.stringify(approved_event.getEventAsJSON()));

          ch.assertExchange(exchange, 'topic', {durable: true});
          ch.publish(exchange, key, msg, {persistent: true});
          console.log(" [x] Sent '%s'", msg);
        }
      }, {noAck: true});
    });
  });
});

比方说,我有2个请求,一个请求要花很长时间才能完成,另一个请求要短一些。较长的请求在较短的请求之前出现。 在我的示例中,长进程为ID === 2,短进程为ID === 1。

现在,如果我发送ID为2的请求,然后立即发送ID为1的请求,则我必须等待10秒钟,第一个完成,然后另一个完成。

我无法理解是否有可能同时处理两个请求,而没有让长流程阻塞短流程直到完成。

1 个答案:

答案 0 :(得分:0)

由于我在SO中没有足够的声誉,因此我无法发表评论,但我会尽力提供尽可能多的见识。

假设sleepthis npm软件包,这是预期的行为,即所谓的blocking行为。如果您打算在消费函数中进行非阻塞调用(例如Web请求),您会很好的,并且节点可以在处理时消费更多消息。但是,如果您需要进行阻塞/ cpu繁重的工作并且仍然能够处理传入的消息,则需要将该工作分担给某些工作人员。

尝试使用此代码,它将“休眠”而不会阻塞:

setTimeout(() => {
    var venue = getVenueByID(pending_event.payload.id);
    const approved_event = new Event("VENUE_TOPIC", "APPROVED_STATUS", false, "READ_METHOD", {
        "venue": venue
    });
    var key = approved_event.getMetaAsTopics();

    var msg = Buffer.from(JSON.stringify(approved_event.getEventAsJSON()));

    ch.assertExchange(exchange, 'topic', {
        durable: true
    });
    ch.publish(exchange, key, msg, {
        persistent: true
    });
    console.log(" [x] Sent '%s'", msg);
}, 10000);