在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
在第二种情况下如何获取值?
答案 0 :(得分:0)
问题不在于将mongodb输出存储到变量中,而是同步和异步行为。设计上的Java脚本是同步的,但具有处理异步任务的能力。执行mongo查询的方法是异步的。阅读:Javascript调用findOne(),这将返回“待处理”的Promise,然后您的脚本继续调用console.log(user)-仍未定义。当来自MongoDB的请求返回时,javascript会解析promise并执行任何进一步的操作和/或回调。
第二个console.log返回并在mongo客户端返回响应并将新值分配给变量之前进行评估。如果您查看响应的时间戳,则未定义的响应会在具有值的响应之前返回。看起来您正在使用猫鼬,它将返回一个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执行,您可能不会引导到相同的容器。您可能会对此产生一些问题。
退房: