Javascript MongoClient GetData例程的NodeJS异步调用
下面的代码混合了 和 当您查看代码下面的console.log时,事情似乎在无序运行。我认为通过使函数异步并使用。然后我可以避免这些问题 我希望MongoDB数据检索功能与app.get功能分开。 没有数据返回到get请求。我猜app.get代码在函数返回值之前就已经完成并结束了。我需要纠正什么Javascript MongoClient GetData例程的NodeJS异步调用,javascript,node.js,async-await,Javascript,Node.js,Async Await,下面的代码混合了 和 当您查看代码下面的console.log时,事情似乎在无序运行。我认为通过使函数异步并使用。然后我可以避免这些问题 我希望MongoDB数据检索功能与app.get功能分开。 没有数据返回到get请求。我猜app.get代码在函数返回值之前就已经完成并结束了。我需要纠正什么 async function getLanguageTranslationData(fromLanguage, toLanguage) { console.log("Started
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
应该返回一个promise
,这样您就可以在处理程序中将其用作承诺,但在您的情况下,调用getLanguageTranslationData
将返回未定义,因为由于nodejs非阻塞性质,此函数中的所有代码将异步执行
因此,您可以这样做,从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);
})
}
})
})
}
然后在处理程序中使用wait来使用返回的承诺
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,根据以下示例,我以这种方式使其工作:
@纳马尔的回答可能也是正确的,但我在他发帖的同时也在测试这个问题。正如上面的StackOverflow问题/答案所指出的,MongoClient的最新版本支持承诺。这篇文章还展示了如何放入一个单独的模块,我可能会在本周晚些时候做这件事
function getLanguageTranslationData(fromLanguage, toLanguage) {
console.log("Started getLanguageTranslationData")
const databaseUrl = "mongodb://localhost:27017"
const databaseName = 'ShedCompanyPOC'
return mongoClient.connect(databaseUrl)
.then(function(conn) {
var collectionName = "UploadedDataeFromExcel";
var dbo = conn.db(databaseName)
var query =
{ $and:
[ {masterLanguage: fromLanguage},
{localizedLanguage: toLanguage}
]
}
console.log("query=" + JSON.stringify(query));
console.log("about to retrieve data");
var collection = dbo.collection(collectionName)
return collection.find(query).toArray();
}).then(function(result) {
console.log("Back from mongoDB.find()")
console.log(JSON.stringify(result))
//conn.close()
return result
});
}
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(function(arrayResult) {
console.log("got arrayResult back from getLanguageTranslationData")
res.status(200).json(arrayResult)
console.log("Backend: End of /api/gettranslations process")
}, function(err) {
console.log("The promise was rejected", err, err.stack)
})
})
在代码中,getLanguageTranslationData
不返回任何内容,因此。然后立即执行,其中arrayResult==undefined
。有很多方法可以重构代码以使其正常工作,但我想最简单的方法就是放弃getLanguageTranslationData
,将其代码移回app.get
,除非您在其他地方需要它-在这种情况下,您应该考虑调用mongoClient.connect()
外部getLanguageTranslationData
,因此您可以让后者返回dbo.collection(collectionName).find(query).toArray()
。谢谢。那么“返回结果”不算作返回?我试图减少嵌套代码的数量,并找出大括号/圆括号错误。最后,它可能是另一个模块中的一个数据访问层。这可能就是我试图做的。它使用回调。我会试试看:谢谢,看看我的其他答案。我在你发帖的同时打字和测试。最新的驱动程序支持承诺,我提到的链接显示了两种方式。