如何为包含 Promises 的 get 函数编写正确的回调?

How to write a correct callback to a get function that includes Promises?

我正在尝试为我的代码编写健康检查(此检查涉及与 Cassandra DB 和 Kafka 的通信)。

这是我写的代码:

// health-check
app.get('/stats/health', function(req, res, next) {
  Promise.all([cassandraPromise, kafkaPromise])
      .then(console.log("Everything is OK"),
      console.log("FAILED!"));
});


var cassandraPromise = new Promise(function(resolve, reject){
  *****.client.state.cassandraClient.execute('SELECT vehicle_id FROM vehicles.vehicles LIMIT 1', function(err) {
    if (err) {
      console.log ('Health Check for Cassandra failed');
      //res.write("Cassandra health check FAILED\n");
      reject(err);
    } else {
      console.log('Health Check for Cassandra passed\n');
      resolve(200);
    }
  });
});

var kafkaPromise = new Promise(function(resolve,reject) {
  stats.kafkaService.producer.send( [{topic: 'health_check', messages: 'health check message'}], function(err,data) {
    if (err) {
      //res.write("Health Check for Kafka failed\n");
      console.log("Health Check for Kafka failed");
      reject(err);
    } else {
      console.log("Health Check for Kafka passed");
      resolve(200);
    }
  });
});

错误信息是:

'queryFetchSize' was not defined. Using default: '25000'

'socketReadTimeout' was not defined. Using default: '30000'

Error in Kafka producer: {"message":"Could not find a broker"}

我有此代码的另一个版本(没有承诺)并且它运行正常,所以我确定我的问题不在 Kafka 上。

你能告诉我我的代码有哪些错误吗?

P.S。我还检查了这个 link:Wrapping Node.js callbacks in Promises using Bluebird 它对我没有帮助。

编辑: 这是工作代码:

// health-check
app.get('/stats/health', cassandraHealthCheck, kafkaHealthCheck);

function cassandraHealthCheck(req, res, next) {
  ******.client.state.cassandraClient.execute('SELECT vehicle_id FROM vehicles.vehicles LIMIT 1', function(err) {
    if (err) {
      console.log ('Health Check for Cassandra failed');
    } else {
      console.log('Health Check for Cassandra passed');
      next();
    }
  });
}

function kafkaHealthCheck(req, res, next) {
    stats.kafkaService.producer.send( [{topic: 'health_check', messages: 'health check message'}], function(err,data) {
      if (err) {
        console.log("Health Check for Kafka failed");
      } else {
        console.log("Health Check for Kafka passed");
      }
    });
};

当你这样做时:

app.get('/stats/health', function(req, res, next) {
  Promise.all([cassandraPromise, kafkaPromise])
});

var cassandraPromise = new Promise(...);
var kafkaPromise = new Promise(...);

您创建了两个将立即加载的承诺。我认为你的 kafka 客户端还没有准备好并且没有兑现承诺。

然后(假设 30 秒后),当您调用 /stats/health 时,您使用两个现有的承诺,它们已经解决Promise.all 以失败的承诺结束(因为 kafkaPromise 30 秒前失败)。

您想做的是每次创建一个新的承诺:

function checkCassandra() {
  return new Promise(...);
}

function checkKafka() {
  return new Promise(...);
}

app.get('/stats/health', function(req, res, next) {
  Promise.all([checkCassandra(), checkKafka()])
});

这样,每次调用健康检查时都会触发对cassandra/kafka的调用。

(我要求工作代码确认,如果我错过了我会更新我的答案)。