javascript - MongoClient GetData 例程的 NodeJS ASync 调用
问题描述
下面的代码混合了https://www.w3schools.com/nodejs/nodejs_mongodb_find.asp 和 https://stackoverflow.com/questions/49982058/how-to-call-an-async-function#:~: text=Putting%20the%20async%20keyword%20before,a%20promise%20to%20be%20resolved。
当您查看代码下方的 console.log 时,事情似乎出了问题。我想通过使函数异步并使用 .then 来避免这些问题。
我希望 MongoDB 数据检索功能与 app.get 功能分开。没有数据返回到 get 请求。我猜 app.get 代码在函数返回值之前已经失败并结束。我需要纠正什么?
async function getLanguageTranslationData(fromLanguage, toLanguage) {
console.log("Started getLanguageTranslationData")
const databaseUrl = "mongodb://localhost:27017"
const databaseName = 'MyCompanyPOC'
mongoClient.connect(databaseUrl, function(err, conn) {
if (err) throw err;
const collectionName = "Phrases";
var dbo = conn.db(databaseName)
var query =
{ $and:
[ {masterLanguage: fromLanguage},
{localizedLanguage: toLanguage}
]
}
console.log("query=" + JSON.stringify(query));
console.log("about to retrieve data");
dbo.collection(collectionName).find(query).toArray(
function(err, result) {
if (err) throw err;
console.log("Back from mongoDB.find()")
console.log(JSON.stringify(result))
return result
conn.close()
})
})
}
app.get("/api/gettranslations/:fromLanguage/:toLanguage",
async function(req, res) {
console.log("Backend: /api/gettranslations method started: " +
" fromLanguage=" + req.params.fromLanguage +
" toLanguage=" + req.params.toLanguage)
getLanguageTranslationData(
req.params.fromLanguage,
req.params.toLanguage)
.then((arrayResult) => {
console.log("got arrayResult back from getLanguageTranslationData")
res.status(200).json(arrayResult)
console.log("Backend: End of /api/gettranslations process")
})
})
Node.JS 控制台输出:
listening on port 3001
Backend: /api/gettranslations method started: fromLanguage=en-US toLanguage=es-MX
Started getLanguageTranslationData
(node:44572) DeprecationWarning: current Server Discovery and Monitoring engine is deprecated, and will be removed in a future version. To use the new Server Discover and Monitoring engine, pass option { useUnifiedTopology: true } to the MongoClient constructor.
got arrayResult back from getLanguageTranslationData
Backend: End of /api/gettranslations process
query={"$and":[{"masterLanguage":"en-US"},{"localizedLanguage":"es-MX"}]}
about to retrieve data
Back from mongoDB.find()
[{"_id":"5f403f7e5036d7bdb0adcd09","masterLanguage":"en-US","masterPhrase":"Customers","localizedLanguage":"es-MX","localizedPhrase":"Clientes"},{ etc...
解决方案
问题是getLanguageTranslationData
应该返回 apromise
以便您可以将其用作处理程序中的承诺,但在您的情况下,调用getLanguageTranslationData
将返回 undefined,因为由于 nodejs的性质,此函数内的所有代码都将异步执行。non-blocking
所以你可以做的是getLanguageTranslationData
像这样从你的函数中返回承诺。
function getLanguageTranslationData(fromLanguage, toLanguage) {
const databaseUrl = "mongodb://localhost:27017"
const databaseName = 'MyCompanyPOC'
return new Promise((resolve, reject)=>{
mongoClient.connect(databaseUrl, function(err, conn) {
if (err) reject(err);
else{
const collectionName = "Phrases";
var dbo = conn.db(databaseName)
var query =
{ $and:
[ {masterLanguage: fromLanguage},
{localizedLanguage: toLanguage}
]
}
dbo.collection(collectionName).find(query).toArray(
function(err, result) {
if (err) reject(err);
else
resolve(result);
})
}
})
})
}
然后在你的处理程序中使用 await 来使用返回的承诺
app.get("/api/gettranslations/:fromLanguage/:toLanguage",
async function(req, res) {
try{
let arrayResult = await getLanguageTranslationData(req.params.fromLanguage, req.params.toLanguage);
res.status(200).json(arrayResult)
}catch(err){
// return error
}
})
上面的代码将为您提供您需要做什么的要点,实际代码可能会根据您的需要而有所不同。
您可以从这里参考async-await
推荐阅读
- tensorflow - 填充=相同时的Keras Conv2D尺寸计算
- android - 关于Android理解VpnService代码的问题
- chicken-scheme - 是否有允许在 Chicken Scheme 中使用符号的 list 简写语法?
- java - 元素类型“META”必须以匹配的结束标签“”结束。使用 XSL 从 XML 文件生成 PDF
- java - 如何重定向jsp
- c++11 - 为什么迭代 bool 的向量需要 &&,而不是 int 的向量?
- python - pyenv python2版本不工作
- ruby - 将 YAML 解析为键值并包含 yaml 类别
- javascript - 从 for 循环多次调用数组,然后删除 0 长度结果
- php - PHP Curl 获取方法