【问题标题】:Promise with recursion, for AMQPLIB reconnection method递归承诺,用于 AMQPLIB 重新连接方法
【发布时间】:2019-12-06 03:31:36
【问题描述】:

我正在创建一个重新连接到 RabbitMQ(使用 amqplib)的方法,使用递归并返回一个传递连接对象的 Promise。这是我目前所拥有的:

function connectServiceBus() {
     return new Promise(function (resolve, reject) {
       amqp.connect(process.env.RMQ_CONN + "?heartbeat=60", function(err, conn) {
         if (err) {
           console.error("[AMQP]", err.message);
           //restarts in 1 sec
           return setTimeout(connectServiceBus, 1000);
         }
         conn.on("error", function(err) {
           if (err.message !== "Connection closing") {
             console.error("[AMQP] conn error", err.message);
             reject(Error("[AMQP] conn error"));
           }
         });
         conn.on("close", function() {
           console.error("[AMQP] reconnecting");
           //restarts in 1 sec
           return setTimeout(connectServiceBus, 1000);
         });

         console.log("[AMQP] ServiceBus Connected");
         resolve(conn);
      });
   });
}

我这样称呼这个方法:

sbus.connectServiceBus().then( function(conn) {
    console.log("Promise called, connection Object Returned: " + conn);
}).catch (err => {
    console.error("Callback ERROR: " + err);
});

问题是,如果我运行它并且 RabbitMQ 正在运行,它就可以工作。如果 RabbitMQ 宕机,代码会重新连接 OK,但永远不会调用 Promise。

如果 RabbitMQ 已关闭,如果 (err) == TRUE 并调用 setTimeout(connectServiceBus, 1000)。由于递归调用,Promise 永远不会被解决,但不知道如何修复它。

我试过替换

return setTimeout(connectServiceBus, 1000);

return resolve(connectServiceBus);

但这也不起作用。

谁能解释我如何解决这个问题,或提供任何见解?

【问题讨论】:

  • 很好,您找到了解决方案,但请注意您的 errorclose 处理程序也相对没有意义。当它们可能运行时,你已经用resolve(conn); 履行了承诺,它的状态不能再改变了。

标签: node.js recursion promise node-amqplib


【解决方案1】:

我找到了一个可行的解决方案。 我替换

return setTimeout(connectServiceBus, 1000);

setTimeout( () => resolve( connectServiceBus() ), 1000 );
return;

编辑:考虑到上面 Bergi 的评论,我更新了我的代码并删除了多余的行。我添加的 return 只是阻止代码退出“if 语句”并执行最终解析。通过添加“else”,就不再需要了。

function connectServiceBus() {
     return new Promise(function (resolve, reject) {
       amqp.connect(process.env.RMQ_CONN + "?heartbeat=60", function(err, conn) {
         if (err) {
           console.error("[AMQP]", err.message);
           //restarts in 1 sec
           setTimeout( () => resolve( connectServiceBus() ), 1000 );
         } else {
           console.log("[AMQP] ServiceBus Connected");
           //keep a reference locally so we can close this connection gracefully on err
           amqpConn = conn;
           resolve(amqpConn);
         }
      });
   });
}

【讨论】:

    猜你喜欢
    • 2015-09-05
    • 2014-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-07
    • 1970-01-01
    相关资源
    最近更新 更多