使用 es7 async/await 检查 mongodb 中是不是存在文档

Posted

技术标签:

【中文标题】使用 es7 async/await 检查 mongodb 中是不是存在文档【英文标题】:Check if document exists in mongodb using es7 async/await使用 es7 async/await 检查 mongodb 中是否存在文档 【发布时间】:2016-01-31 17:58:10 【问题描述】:

我正在尝试检查email 提供的用户是否存在于集合users 中,但我的函数每次调用都会返回未定义。我使用 es6 和 async/await 来消除大量回调。这是我的函数(它在一个类中):

async userExistsInDB(email) 
    let userExists;
    await MongoClient.connect('mongodb://127.0.0.1:27017/notificator', (err, db) => 
        if (err) throw err;

        let collection = db.collection('users');

        userExists = collection.find(email: email).count() > 0;
        console.log(userExists);

        db.close();
    );
    console.log(userExists);
    return userExists;

所以,.connect 调用中的第一个console.log 总是返回false,因为.find 的返回值不是一个数组,它是一个看起来像这样的巨大对象:

 connection: null,
  server: null,
  disconnectHandler: 
    s:  storedOps: [], storeOptions: [Object], topology: [Object] ,
     length: [Getter] ,
  bson: ,
  ns: 'notificator.users',
  cmd: 
    find: 'notificator.users',
     limit: 0,
     skip: 0,
     query:  email: 'email@example.com' ,
     slaveOk: true,
     readPreference:  preference: 'primary', tags: undefined, options: undefined  ,
  options: 
........
........

而最后一个console.log 总是未定义(虽然我认为它不应该是那样的,因为await 等待异步调用结束,对吧?)


我只需要我的函数返回一个布尔值,而不是 Promise 之类的。

有人可以帮我吗?

更新 1

console.log(collection.findOne(email: email));.connect 内返回:

  'Symbol(record)_3.ugi5lye6fvq5b3xr': 
    p: [Circular],
     c: [],
     a: undefined,
     s: 0,
     d: false,
     v: undefined,
     h: false,
     n: false  

更新 2

这似乎是我对 es7 async/await 了解不足的问题。

现在.connect 中的代码返回所需的值。

async userExistsInDB(email) 
    let userExists;
    await* MongoClient.connect('mongodb://127.0.0.1:27017/notificator', async(err, db) => 
        if (err) throw err;

        let collection = db.collection('users');
        userExists = await collection.find(email: email).limit(1).count() > 0;

        db.close();
    );
    console.log(userExists); // <--- this is not called at all
    return userExists;

但是,现在根本不执行 console.log.connect 调用之后的任何内容。

现在,每次我在某处调用 userExistsInDB() 函数并调用 console.log 其结果时,我都会得到:

  'Symbol(record)_3.78lmjnx8e3766r': 
    p: [Circular],
     c: [],
     a: undefined,
     s: 0,
     d: false,
     v: undefined,
     h: false,
     n: false  

你知道为什么会这样吗?

【问题讨论】:

不要使用count(),即使在找到第一个这样的文档之后,您也要求 mongodb 继续计数。只需使用findOne() 并查看它是否返回具有相同email 的任何内容。 请看更新。顺便说一句,我在某处读到使用findOne() 比使用find().limit(1) 慢得多,您对此有何看法? @Dennis find().limit(1).count() 确实是一个很好的优化。 mongo automatically does this 在其 findOne() 实现中的 javascript 驱动程序。 【参考方案1】:

好的,这就是我的工作方式:

async function userExistsInDB(email, password) 
    let db = await MongoClient.connect('mongodb://127.0.0.1:27017/notificator');
    try 
        let collection = db.collection('users');
        let userCount = (await collection.find(
            
                email: email,
                password: password
            ).limit(1).count());
        return userCount > 0;
     finally 
        db.close();
    

因为函数声明中的async 关键字保证返回值将是Promise,所以从这个函数中获得真正返回结果的唯一方法是:

let result = await this.userExistsInDB(email, password); 在另一个声明为 async 的函数中。

【讨论】:

对自己有用的@note :)

以上是关于使用 es7 async/await 检查 mongodb 中是不是存在文档的主要内容,如果未能解决你的问题,请参考以下文章

异步操作要了解的ES7的async/await

理解ES7中的async/await

ES7的Async/Await的简单理解

ES7 async await

ES7 async await

关于ES7里面的async和await