简体   繁体   English

无法返回从 mongodb 获取的数据

[英]Cannot return data fetched from mongodb

I can successfully fetch all data stored in a collection called "topics" by using find() with cursor and foreach.通过使用带有 cursor 和 foreach 的 find(),我可以成功获取存储在名为“主题”的集合中的所有数据。 However, when I try to set the fetched information to variable call "data" and send it back to the page, it always display an empty array.但是,当我尝试将获取的信息设置为变量调用“数据”并将其发送回页面时,它总是显示一个空数组。

How can I fix it?我该如何解决?

app.get('/api/get_topics', (req, res)=>{
    let data = [];
    MongoClient.connect(url, (err, db)=>{
        const dbo = db.db('adoption');
        let cursor = dbo.collection('topics').find();
        cursor.forEach((el)=>{
            const obj = {
                img     : el.img,
                title   : el.title,
                content : el.content
            }
            data.push(obj);
        });
        db.close();
    });
    res.json(data); // [] ---> always empty
    res.end();
});

try this尝试这个

app.get('/api/get_topics', (req, res)=>{
    let data = [];
    MongoClient.connect(url, (err, db)=>{
        const dbo = db.db('adoption');
        let cursor = dbo.collection('topics').find();
        cursor.forEach((el)=>{
            const obj = {
                img     : el.img,
                title   : el.title,
                content : el.content
            }
            data.push(obj);
        });
        db.close();
        res.json(data); // [] ---> always empty
        res.end();
    });
});

You need to return the data after your connection to the database is done.完成与数据库的连接后,您需要返回数据。 Before you close the connection and after your forEach : because "forEach" is syncron & blocks the event loop在你关闭连接之前和你的forEach之后:因为“forEach”是同步的并且阻塞了事件循环

 app.get('/api/get_topics', (req, res)=>{ let data = []; MongoClient.connect(url, (err, db)=>{ const dbo = db.db('adoption'); let cursor = dbo.collection('topics').find(); cursor.forEach((el)=>{ const obj = { img: el.img, title: el.title, content: el.content } data.push(obj); }); res.json(data); res.end(); db.close(); }); });

Note: You should create a global connection and not for every request.注意:您应该创建一个全局连接,而不是针对每个请求。 A connection can be re used.可以重新使用连接。

The reason for the empty data is because MongoClient.connect() is an asynchronous function, meaning the code is not waiting for your callback to push the content to your data array before setting the response data.data的原因是因为MongoClient.connect()是一个异步的 function,这意味着代码在设置响应数据之前不会等待您的回调将内容推送到您的data数组。

As others have pointed out, you can set and end your response within your callback, but I am skeptical that that will work.正如其他人指出的那样,您可以在回调中设置和结束您的响应,但我怀疑这是否可行。 Another approach would be to use an async/await method .另一种方法是使用async/await方法 You can see this usage from the official MongoDB docs .您可以从官方 MongoDB 文档中看到这种用法

In addition, I believe you can omit res.end() or move it to the catch.此外,我相信您可以省略res.end()或将其移至 catch。

For example:例如:

app.get('/api/get_topics', (async (req, res) => {
    try {
        let data = [];
        const db = await MongoClient.connect(url);
        const dbo = db.db('adoption');
        const cursor = dbo.collection('topics').find();
        cursor.forEach((el)=>{
            const obj = {
                img     : el.img,
                title   : el.title,
                content : el.content
            }
            data.push(obj);
        });
        db.close();
        res.json(data);
    } catch (err) {
        // Handle an error here...
        console.log(err);
        res.end();
    }
}));

MongoClient.connect(url, callback) ... MongoClient.connect(url, callback) ...

Which hints that the connect() fnc is an async function.这暗示 connect() fnc 是异步 function。 Hence res.json(data);因此 res.json(data); res.end();重发(); will be executed before the callback of the connect function is being called where you populate your array.将在您填充数组的位置调用连接 function 的回调之前执行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM