繁体   English   中英

如何使用用TypeScript编写的Node.js连接到MongoDB?

[英]How to connect to MongoDB using Node.js written in TypeScript?

我正在使用Node.js服务器,连接到MongoDB并使用TypeScript编写。 当我尝试使用MongoDB时,它不会创建连接,但是当我检查mongo输出时,它的确会创建连接。

在Node.js中定义连接的代码中缺少什么?

我的连接字符串是'mongodb://localhost:27017'

我的连接方法:

connect() {
    console.log('connecting to mongo') //this is called
    MongoClient.connect(this.connectionString, {useNewUrlParser: true})
    .then(client => {
        console.log('setting client'); //this doesn't get called
        this.client = client;
        console.log(this.client);
    })
    .catch(error => {
        console.log('error during connecting to mongo: '); //this also doesn't get called
        console.error(error);
    });
}

Mongo输出:

2018-11-08T23:06:24.106 + 0100我接受127.0.0.1:51345#11的NETWORK [listener]连接(2个连接现已打开)

2018-11-08T23:06:24.107 + 0100我网络[conn11]从127.0.0.1:51345 conn11收到客户端元数据:{驱动程序:{名称:“ nodejs”,版本:“ 3.1.9”},os:{类型:“ Darwin”,名称:“ darwin”,体系结构:“ x64”,版本:“ 17.7.0”},平台:“ Node.js v8.9.3,LE,mongodb-core:3.1.8”}

我的存储库位于https://github.com/FrisoDenijs/MEAN-ToDo/blob/master/server/src/db/mongo.db.ts ,以获取完整代码。

shkaper要求的console.log(db)

MongoClient {
  domain: null,
  _events: {},
  _eventsCount: 0,
  _maxListeners: undefined,
  s:
   { url: 'mongodb://localhost:27017',
     options:
      { servers: [Array],
        caseTranslate: true,
        useNewUrlParser: true,
        socketTimeoutMS: 360000,
        connectTimeoutMS: 30000,
        promiseLibrary: [Function: Promise] },
     promiseLibrary: [Function: Promise],
     dbCache: {},
     sessions: [] },
  topology:
   Server {
     domain: null,
     _events:
      { serverOpening: [Function],
        serverDescriptionChanged: [Function],
        serverHeartbeatStarted: [Function],
        serverHeartbeatSucceeded: [Function],
        serverHeartbeatFailed: [Function],
        serverClosed: [Function],
        topologyOpening: [Function],
        topologyClosed: [Function],
        topologyDescriptionChanged: [Function],
        commandStarted: [Function],
        commandSucceeded: [Function],
        commandFailed: [Function],
        joined: [Function],
        left: [Function],
        ping: [Function],
        ha: [Function],
        authenticated: [Function],
        error: [Function],
        timeout: [Function],
        close: [Function],
        parseError: [Function],
        open: [Object],
        fullsetup: [Object],
        all: [Object],
        reconnect: [Function] },
     _eventsCount: 25,
     _maxListeners: Infinity,
     clientInfo:
      { driver: [Object],
        os: [Object],
        platform: 'Node.js v8.9.3, LE' },
     s:
      { coreTopology: [Object],
        sCapabilities: null,
        clonedOptions: [Object],
        reconnect: true,
        emitError: true,
        poolSize: 5,
        storeOptions: [Object],
        store: [Object],
        host: 'localhost',
        port: 27017,
        options: [Object],
        sessionPool: [Object],
        sessions: [],
        promiseLibrary: [Function: Promise] } } }

问题是因为mongo.connect是异步代码,并且控制器错误地调用它。 因此后续行mongo.getDb()将在未正确启动this.client情况下执行。

由于您使用的是Typescript,因此我们可以使用async/await获得更清晰的代码。

async connect() { // add async
    console.log('connecting to mongo');

    try {
      if (!this.client) { // I added this extra check
        console.log('setting client');
        this.client = await MongoClient.connect(this.connectionString, { useNewUrlParser: true })
        console.log(this.client);      
      }
    } catch(error) {
      console.log('error during connecting to mongo: ');
      console.error(error);
    }    
}

并在控制器代码中

async get(req: Request, res: Response) { // add async
  const mongo = new MongoDb();
  await mongo.connect(); // add await
  const db = mongo.db(); 
  // ....     
}

我尝试了您的回购并进行了更改,并收到了此回复

在此处输入图片说明

希望能帮助到你

根据您所说的关于既不调用错误也不调用成功回调的说法,我认为问题不仅存在于以下代码中: https : //github.com/FrisoDenijs/MEAN-ToDo/blob/master/server/src/db/mongo .db.ts但也例如在这里: https : //github.com/FrisoDenijs/MEAN-ToDo/blob/master/server/src/controllers/to-do.controller.ts运行mongo.connect ,应该有一个等待MongoClient.connect返回的承诺的选项。 因此,我会将mongo.db.ts代码更改为例如这样(取决于您如何处理此承诺):

connect() {
    console.log('connecting to mongo')
    return MongoClient.connect(this.connectionString, {useNewUrlParser: true})
    .then(client => {
        console.log('setting client');
        this.client = client;
        console.log(this.client);
    })
    .catch(error => {
        console.log('error during connecting to mongo: ');
        console.error(error);
    });
}

然后,在to-do.controller.ts可以await这个或使用then

get(req: Request, res: Response) {
    const mongo = new MongoDb();
    mongo.connect().then(() => {

      const db = mongo.getDb();
      const collection = db.collection('todo', (error, collection) => {
          if (error) {
              res.json(error);
              res.statusCode = HttpStatus.BAD_REQUEST
              return;
          }

          collection.find().toArray((error, result) => {
              if (error) {
                  res.json(error);
                  res.statusCode = HttpStatus.BAD_REQUEST
              }

              res.json(result);
              res.statusCode = HttpStatus.OK;
          })

      });

      mongo.close();
    });
} 

我想您的代码只是不“等待”建立连接,然后失败。

上面的解决方案确实有效,但是还有另一种我更喜欢的方法。 它更像是一个标准的HTTP调用(无论是否有异步等待,我都可以使用它,但是最好保留它):

private async connect(){
    this.mongo = new mongodb.MongoClient(this.url, {useNewParser: true});
    await this.mongo.connect((err, client) => {
        if(client.isConnected()){
            console.log('setting client');
            this.client = client;
            console.log(this.client);
        }
        else{
            console.log('error during connecting to mongo: ');
            console.error(error);
        }
    });
}

这基于Node.js驱动程序api v3.2,您可以在此处查看: https : //mongodb.github.io/node-mongodb-native/3.2/api/index.html

可能只是用另一种方式剃猫而已,但我认为值得以后在这里碰到的其他人分享。

暂无
暂无

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

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