在下面的代码中,我只是从mongodb访问一些数据并将其存储在变量中。现在,我想在CustomCardView
函数中使用此变量。但是当我尝试将其简单地显示为mongodb.connect()
。
我知道这是JavaScript异步内容。我浏览过多个有关回调,承诺和异步/等待的网站,但我听不懂这些主题。
任何人都可以对我的代码进行一些简单的修改。
undefined
预期输出:app.get('/',function(req,res){
var data;
mongodb.connect(url,{useNewUrlParser:true},(err,db)=>{
var dbo=db.db('pract')
var cursor=dbo.collection('samp').find({_id:1410})
cursor.forEach(function(doc){
data=doc;
})
})
console.log(data)
res.end()
})
实际输出:{name:'vasu',age:20}
答案 0 :(得分:1)
我建议您使用从最近的Javascript版本开始引入的新async await functionality。由于它看起来像普通的同步代码,因此更易于推理。掌握Javascript的异步细微差别将花费一些时间,但是最终您将需要它来了解Javascript如何使用多种异步方法(承诺,回调等)工作。
我能想到的使用express&MongoDB的最短的异步/等待代码是这样的:
const MongoClient = require('mongodb').MongoClient
const express = require('express')
const app = express()
var conn
app.get('/', async (req, res) => {
var output = await conn.db('test').collection('test').find().toArray()
res.send(output)
})
var run = async function() {
conn = await MongoClient.connect('mongodb://localhost:27017/test', {useNewUrlParser: true})
await app.listen(3000)
console.log('listening on 3000')
}
run()
使用curl "http://localhost:3000"
应该在test
数据库中打印test
集合的内容。
一些注意事项:
conn
是一个全局变量,允许MongoDB驱动程序正确使用连接池。一次连接,然后在各处重复使用连接。不要为每个请求一直连接到数据库。run()
方法建立数据库连接,然后开始侦听。这样,您可以确保数据库已准备就绪。否则,您的应用程序可以在数据库准备就绪之前开始监听。try {...} catch {...}
。此代码已在节点12.4.0,MongoDB节点驱动程序3.2.7和Express 4.17.1上进行了测试
如果发现此代码无效,请确保可以连接到数据库。
答案 1 :(得分:0)
一旦收到GET请求,您的应用程序就连接到数据库。这是异步工作。因此需要一些时间才能得到结果。但是console.log不会等待此异步操作。
因为连接到数据库操作将被发送到事件循环。 console.log具有比事件循环更高的优先级。因此console.log将首先执行,并且在执行过程中,数据没有任何值,因此它返回的是undefined。(我只是碰触了事件循环,这是您应该了解的问题)。
解决方案:
app.get('/',function(req,res){
//var will make it global, avoid using var.
let data;
mongodb.connect(url,{useNewUrlParser:true},(err,db)=>{
var dbo=db.db('pract')
var cursor=dbo.collection('samp').find({_id:1410})
cursor.forEach(function(doc){
data=doc;
console.log(data)
//we are inside the for each function which is inside the callback db function.
//that means console.log is inactive till connection is successfully done.
//find function is also async function but console.log cannot access to data from here.
//it can access only one level above function's variables.
//forEach function is sync so it will run the data=doc first then console.log the data.
//make sure you already have the data inside the connected database.
})
})
res.end()
})
此语法非常古老。尝试学习promise和async / await