node.js - 如何在 lambda 函数中使用 nodejs 将 mongodb 输出存储在变量中?
问题描述
在 lambda 函数中,我有以下代码:
var user;
exports.handler = function uploadToS3(event, context, callback) {
var name = event["username"];
MongoClient.connect(uri, { useNewUrlParser: true }, (error, client) => {
if (error) return 1; // Checking the connection
db = client.db(databasename);
db.collection("user_profile").findOne({ username: name }, function(
err,
result
) {
if (err) throw err;
user = result._id;
console.log(user); // 1st console.log
});
});
console.log(user); //2nd console.log
};
在上面的代码中,我将 user 声明为全局变量。在第一个 console.log 中它将显示该值,但在第二个 console.log 中它将未定义。找到以下 lambda 函数的输出。
Function Logs:
2019-08-23T15:23:34.610Z 83141f62-f840-4e52-9440-35f3be7b0dc8
5d5eaa9f921ed00001ee1c3f
2019-08-23T15:23:34.192Z 83141f62-f840-4e52-9440-35f3be7b0dc8
undefined
在第二种情况下如何获得价值?
解决方案
问题不在于将 mongodb 输出存储到变量中,而在于它是同步与异步行为。Javascript 在设计上是同步的,但具有处理异步任务的能力。执行 mongo 查询的方法是异步的。阅读:Javascript 调用 findOne(),这会返回一个“待定”的承诺,然后你的脚本继续调用 console.log(user) - 这仍然是未定义的。当来自 MongoDB 的请求返回时,javascript 解析承诺并执行任何进一步的操作和/或回调。
第二个 console.log 在 mongo 客户端返回响应并为您的变量分配一个新值之前返回并进行评估。如果您查看响应的时间戳,未定义的会在具有值的时间戳之前返回。看起来您正在使用 mongoose,它应该返回一个 Promise,您可以尝试将第二个调用放在 .then 或 .done 块中。例如:
var user;
exports.handler = function uploadToS3(event, context, callback) {
var name = event["username"];
MongoClient.connect(uri, { useNewUrlParser: true }, (error, client) => {
if (error) return 1; // Checking the connection
db = client.db(databasename);
db.collection("user_profile").findOne({ username: name }, function(
err,
result
) {
if (err) throw err;
user = result._id;
console.log(user); // 1st console.log
})
.done(function(){
console.log(user); //2nd console.log
});
});
};
如果不使用猫鼬......做出你自己的承诺,或者使用回调,或者只是尝试猫鼬(它摇滚!):)
*请注意,我将 .done 放在 findOne() 之后,但我相信您也可以将 .done() 附加到 .connect()。(不要引用我的话。您必须对其进行测试,看看该承诺何时准确解决)
此外,我建议以某种方式将此值存储在您的 lambda 之外。您可能不会为每个 lambda 执行引导相同的容器。你可能会遇到一些问题。
查看:
- 全局变量的 AWS Lambda 缓存问题 - https://medium.com/tensult/aws-lambda-function-issues-with-global-variables-eb5785d4b876
- 通过使用全局变量提高 Lambda 函数的性能 - https://blog.ruanbekker.com/blog/2018/08/27/improving-performance-from-your-lambda-function-from-the-use-of -全局变量/
- AWS Lambda 最佳实践 - https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html
推荐阅读
- loops - 如何将前导零添加到宏变量?
- matlab - MATLAB如何确保在我的色标中不考虑颤动?
- reactjs - “提交”按钮需要点击两次才能提交 React Js
- sql - 如何在sql server的变量中包含2个单引号
- r - 如何在使用 Rshiny 输入可编辑数据表时冻结行?
- opengl-es - OpenGL ES 3.x 如何(高效地)使用 alpha 混合和早期拒绝遮挡片段从前到后渲染混合三角形?
- html - HTML/CSS - 如何使全屏 videoJS 播放器适合浏览器窗口?
- ansible - 将 Ansible stat 的 mtime 输出转换为 YYMMDD-HHMMSS
- javascript - Python“服务器”+ JS客户端websocket 1006错误
- python - 对字典中列表的某些值求和