首页 > 解决方案 > 从 CosmosDb 读取的 Azure JavaScript 函数连接但查询超时且无输出

问题描述

我正在为一个工作项目学习 Azure 函数和 CosmosDb。我相信我已经解决了我需要的大部分内容,但是我的 Azure JS 函数查询正在运行,但是超时并且什么也没有返回。以下是我的完整功能代码、我的日志输出和显示数据的 CosmosDb 数据资源管理器的剪辑。您可以通过日志输出看到查询正在执行,但它总是超时。

我正在传递:monsterId=5cc1b65f7dfa950cd42a5b8e 在查询字符串上。

let mongoClient = null;

module.exports = (context, req) => {
	const monsterId = req.query.monsterId;
	if (!monsterId) {
		context.res = {
			status: 400,
			body: "Please pass a 'monsterId' in the query string"
		};
		context.done();
	} else {
		function runQuery() {
			// Run the getMonster query
			const query = {
				"id": monsterId,
				"del": false
			};
            context.log('Running query now...');
			mongoClient.db('mfw-dev').collection('monsters')
				.findOne(query)
				.then(doc => {
					context.res = {
						body: { "monster": doc },
					};
					context.done();
				}, error => {
					context.err('Monster find error: ', error);
					context.res = {
						status: 400,
						body: { "error": "Monster find error: " + error },
					};
					context.done();
				});
		};

		if (mongoClient != null) {
		    runQuery();
        } else {
			mongoClient = require("mongodb").MongoClient;
			const uri = process.env.COSMOS_CONN;
			mongoClient.connect(uri, { useNewUrlParser: true })
				.then(client => {
					context.log('MongoClient connected!!!...');
					//mongoClient = client;
					runQuery();
				}, error => {
					context.err('MongoClient connect error: ', error);
					context.res = {
						status: 400, /* Defaults to 200 */
						body: { "message": "MongoClient connect error: " + error },
					};
					context.done();
				});
		}
	}

};

Azure 函数日志输出

在此处输入图像描述

标签: javascriptfunctionazureazure-cosmosdb

解决方案


这里的主要问题是您正在使用静态Mongo 客户端而不是返回的、已连接的实例进行查询。总的来说,这一切看起来比它需要的要复杂得多。

const MongoClient = require('mongodb').MongoClient;
const { COSMOS_CONN } = process.env;
let client = null;

module.exports = async (context, req) => {
  const monsterId = req.query.monsterId;
  if (monsterId) {
    client = client || await MongoClient.connect(COSMOS_CONN, { useNewUrlParser: true });
    context.log('Running query now...');
    const monster = await client
      .db('mfw-dev')
      .collection('monsters')
      .findOne({
        id: monsterId,
        del: false
      });
    context.res = {
      body: { monster },
    };
  } else {
    context.res = {
        status: 400,
        body: "Please pass a 'monsterId' in the query string"
    };
  }
};

您会注意到这里的主要区别是:

  • 我不在context.done任何地方打电话
  • 我没有处理任何错误

这是因为在函数完成context.done时会自动调用,如果在任何时候任何调用抛出,错误都会被自动捕获并记录下来。asyncasync

需要注意的一点是,您可能希望在 MongoClient 设置周围有一些更强大的东西,即最好检查客户端是否存在连接,但我会让你做一些细节:)


推荐阅读