Javascript nodejsmongodb:如何获取数据然后同步返回

Javascript nodejsmongodb:如何获取数据然后同步返回,javascript,node.js,mongodb,express,async-await,Javascript,Node.js,Mongodb,Express,Async Await,我是一名长期程序员(主要是Java),但对NodeJS/Express还不熟悉。我遇到的最大问题是异步操作。我的一些代码工作正常,比如我可以执行异步数据库操作,然后将结果传递给res.render() 在这种特殊情况下,我在一个路由处理程序中,我需要调用我在控制器中编写的函数,从数据库中获取一些信息,然后执行其他操作,然后在路由处理程序中进行渲染。换句话说,我需要运行这个函数,然后将控制结果返回给路由器。我所尝试的一切甚至都不是编译,只是挂起,或者我立即返回两个未定义的值。我当前的模式与中接受的

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

在这种特殊情况下,我在一个路由处理程序中,我需要调用我在控制器中编写的函数,从数据库中获取一些信息,然后执行其他操作,然后在路由处理程序中进行渲染。换句话说,我需要运行这个函数,然后将控制结果返回给路由器。我所尝试的一切甚至都不是编译,只是挂起,或者我立即返回两个未定义的值。我当前的模式与中接受的解决方案类似,但我无法收回数据

我真的试着去理解这个异步/等待的东西,但它并没有像我期望的那样工作

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

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 };
    }
我调用的函数如下所示:

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的调试输出之前,我先看到路由处理程序的调试输出。因此,我不觉得路由处理程序正在等待数据返回


你能提供的任何帮助都会很好。我已经读了这么多页了,但我还是不明白。谢谢。

toArray函数也会返回一个承诺,因此如果您使用的是async/Wait,您可以在listInsightPeriods函数中尝试这种方法

异步函数listInsightPeriods(){ 常数响应={ listInsightErrors:null, listInsightResults:null } 试一试{ 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(); 调试(“listInsightPeriods获得的结果:%O”,结果); response.listInsightResults=结果; }捕获(e){ 调试(“listInsightPeriods查找错误:%O”,e); response.listInsightErrors=e; } 返回响应; }
toArray函数还返回一个承诺,因此如果您使用的是async/Wait,您可以在listInsightPeriods函数中尝试这种方法

异步函数listInsightPeriods(){ 常数响应={ listInsightErrors:null, listInsightResults:null } 试一试{ 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(); 调试(“listInsightPeriods获得的结果:%O”,结果); response.listInsightResults=结果; }捕获(e){ 调试(“listInsightPeriods查找错误:%O”,e); response.listInsightErrors=e; } 返回响应; }
您可以使用“回调”概念

这太棒了

这段代码是为你和我测试的。工作还可以

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)
  // });
}

您可以使用“回调”概念

这太棒了

这段代码是为你和我测试的。工作还可以

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)
  // });
}

谢谢加布里埃尔。你是对的,但是我错过了一件事,那就是阻止我让它按我认为应该的方式工作,那就是把整个事情置于一个“尝试/抓住”的障碍中。然后我可以返回find()的结果。谢谢Gabriel。你是对的,但是我错过了一件事,那就是阻止我让它按我认为应该的方式工作,那就是把整个事情置于一个“尝试/抓住”的障碍中。然后我可以从find()返回结果。