【问题标题】:NodeJS MongoDB: How do I get data then returning synchronouslyNodeJS MongoDB:我如何获取数据然后同步返回
【发布时间】:2020-08-19 13:28:16
【问题描述】:

我是一名长期程序员(主要是 Java),但对 NodeJS/Express 不熟悉。我遇到的最大问题是异步操作。我的一些代码运行良好,比如我可以执行异步数据库操作,然后将结果传递给 res.render()。

在这种特殊情况下,我在路由处理程序中,我需要调用我在控制器中编写的函数以从数据库中获取某些内容,然后执行其他操作,然后在路由中进行渲染处理程序。换句话说,我需要运行该函数,然后将带有结果的控制权返回给路由器。我尝试过的一切都没有编译,只是挂起,或者我立即返回两个未定义的值。我目前的模式类似于mongoDB with nodejs return data 中接受的解决方案,但我没有取回我的数据。

我真的试图理解这个 async/await 的东西,但它并没有像我预期的那样工作。

路由处理程序中的调用者如下所示:

app.get('/', async (req, res) => {
    debug("app calling list:");
    const { listInsightErrors, listInsightResults } = await listInsightPeriods();
    debug("app results: %O %O", listInsightErrors, listInsightResults);
    res.render('index', {
        appConfig,
        listInsightErrors,
        listInsightResults
    });
});

我正在调用的函数如下所示:

async function listInsightPeriods() {
        var sortKey = { clientId: 1, insightName: 1 };
        var listInsightErrors = {};
        var listInsightResults = {};
        client = await MongoClient.connect(appConfig.mongoUrl);
        const db = client.db(appConfig.mongoDatabase);
        const collection = db.collection('teamInsights');
        let garbage = await collection.find({})
            .project({ 'clientName': 1, 'insightName': 1 })
            .sort(sortKey)
            .toArray((errors, results) => {
                if (errors) {
                    debug('listInsightPeriods find error: %O', errors);
                } else {
                    debug('listInsightPeriods got results: %O', results);
                }
                listInsightErrors = errors;
                listInsightResults = results;
                debug("closed, returning %O %O", listInsightErrors, listInsightResults);
                return { listInsightErrors, listInsightResults };
                debug("Passed inside return");
            });
        debug("Outside of db call");
        return { listInsightErrors, listInsightResults };
    }

发生的情况是 listInsightPeriods 可以很好地获取数据,但路由处理程序没有得到它,并且在我看到来自 listInsightPeriods 的调试输出之前,我看到了路由处理程序的调试输出。所以我不觉得路由处理程序在等待数据返回。

您能提供的任何帮助都会很棒。我已经阅读了很多关于此的页面,但我仍然无法理解。谢谢。

【问题讨论】:

    标签: javascript node.js mongodb express async-await


    【解决方案1】:

    toArray 函数也返回一个 Promise,所以如果你使用 async/await,你可以在你的 listInsightPeriods 函数中尝试这种方法

    async function listInsightPeriods() {
      const response = {
        listInsightErrors: null,
        listInsightResults: null
      }
      try{
        client = await MongoClient.connect(appConfig.mongoUrl);
        const db = client.db(appConfig.mongoDatabase);
        const collection = db.collection('teamInsights');
        const results  = await collection.find({})
            .project({ 'clientName': 1, 'insightName': 1 })
            .sort({ clientId: 1, insightName: 1 })
            .toArray();
        debug("listInsightPeriods got results: %O", results);
        response.listInsightResults = results;
      }catch(e){
        debug("listInsightPeriods find error: %O", e);
        response.listInsightErrors = e;
      }
    
      return response;
    }
    

    【讨论】:

    • 谢谢加布里埃尔。你是对的,但是我错过的事情是阻止我让它按照我认为应该的方式工作,那就是把整个事情放在一个 try/catch 块中。然后我可以从 find() 返回结果。
    【解决方案2】:

    您可以使用“回调”概念。

    回调是惊人的。

    这段代码是为你和我测试的。没问题。

    const express = require("express")
    const mongo = require("mongodb")
    const app = express()
    
    const appConfig = {
      mongoUrl: "mongodb://127.0.0.1:27017/local",
      mongoDatabase: "local"
    }
    
    let client;
    let dataBase;
    mongo.connect(appConfig.mongoUrl, {}, (err, client) => {
      if (err) {
        this.client = null;
        this.dataBase = null;
        return;
      }
      client = client;
      dataBase = client.db(appConfig.mongoDatabase);
      debug("connected to database");
    });
    
    app.listen(4000, () => {
      debug("Server is listening on port: 4000");
    })
    
    app.get("/", (req, res) => {
      debug("app calling list:");
      listInsightPeriods(function (error, result) {
        debug("app results: %O %O", error, result);
        res.json({
          error,
          result
        })
        // res.render("index", {
        //   appConfig,
        //   error,
        //   result
        // });
      });
    });
    
    function listInsightPeriods(callback) {
      var sortKey = { clientId: 1, insightName: 1 };
      dataBase.collection("teamInsights")
        .find({})
        .project({ clientName: 1, insightName: 1 })
        .sort(sortKey)
        .toArray((errors, results) => {
          if (errors) {
            debug("listInsightPeriods find error: %O", errors);
          } else {
            debug("listInsightPeriods got results: %O", results);
          }
          debug("closed, returning %O %O", errors, results);
          return callback(errors, results);
        });
    }
    
    function debug(...params) {
      console.log(params)
      // params.forEach(param => {
      //   console.log(param)
      // });
    }
    

    【讨论】:

      猜你喜欢
      • 2018-05-23
      • 2021-05-17
      • 1970-01-01
      • 1970-01-01
      • 2021-05-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多