NodeJS MongoDB:如何获取数据然后同步返回

问题描述 投票:0回答:2

我是一个长期的程序员(主要是Java),但是对NodeJS / Express还是陌生的。我遇到的最大问题是异步操作。我的某些代码工作正常,例如当我可以执行异步数据库操作时,只需将结果传递给res.render()。

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

我确实尝试理解异步/等待的内容,但是它没有按我期望的那样工作。

路由处理程序中的呼叫者看起来像这样:

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
2个回答
0
投票

toArray函数还返回Promise,因此,如果您使用的是异步/等待,则可以在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;
}

0
投票

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

回叫很棒。

此代码适用于您,我已经测试过。可以。

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)
  // });
}
© www.soinside.com 2019 - 2024. All rights reserved.