问题 使用es7 async / await检查mongodb中是否存在文档


我正在尝试检查用户是否有 email 提供存在于集合中 users,但我的函数一直为每次调用返回undefined。我使用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;
}

所以,第一个 console.log 在 - 的里面 .connect 电话总是回来 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 } }

任何想法为什么会这样?


9344
2017-10-31 10:52


起源

不要用 count(),你要求mongodb继续计数,即使在找到第一个这样的文件之后。只是用 findOne() 并查看它是否返回任何相同的内容 email。 - S.D.
请参阅更新。顺便说一下,我读过某个地方使用过 findOne() 比使用慢 find().limit(1)你会怎么说呢? - Denis Yakovenko
@Dennis find().limit(1).count() 确实是一个很好的优化。 mongo的JavaScript驱动程序 自动这样做 在它的 findOne() 实现。 - S.D.


答案:


好的,这是我如何运作:

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 函数声明中的关键字 担保 返回的值将是a Promise,从这个函数中获得真实返回结果的唯一方法是:

let result = await this.userExistsInDB(email, password); 在另一个函数内部声明 async


12
2017-11-02 07:37



有用的@note自我:) - dcsan
哇!太感谢了!这很简单! - bozzmob