await, похоже, не ждет завершения асинхронного вызова

У меня есть асинхронная функция, которая использует вызовы await, и я подумал, что когда вы используете await, она должна приостановить выполнение функции до тех пор, пока не будет получено значение. У меня почему-то не работает.

Вот моя функция (она находится внутри класса):

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;
        console.log("INSIDE:\n", userExists);
        db.close();
    });
    console.log("OUTSIDE:\n", userExists);
    return userExists;
}

И вот как я вызываю это в другой функции внутри того же класса:

async getValidationErrors(formData) {
   let userExists = await this.userExistsInDB(formData.email);
   console.log("ANOTHER FUNC:\n", userExists);
}

Итак, я получаю следующий вывод:

OUTSIDE:
 undefined
ANOTHER FUNC:
 undefined
INSIDE:
 true

хотя значение INSIDE: true я ожидаю, что оно будет напечатано первым.

По сути, мне нужно получить логическое значение userExists из функции userExistsInDB и использовать его в другом коде.

Что я здесь делаю неправильно?


person Denis Yakovenko    schedule 31.10.2015    source источник


Ответы (1)


await работает только с промисами, поэтому MongoClient.connect(…) нужно будет вернуть промис. Тем не менее, вы используете его как API обратного вызова, и даже с функцией обратного вызова async (возврат обещаний), которая не будет работать. Предполагая, что монго возвращает обещания, если вы не передаете обратный вызов, ваш код должен выглядеть так:

async function userExistsInDB(email) {
    let db = await MongoClient.connect('mongodb://127.0.0.1:27017/notificator');
    let collection = db.collection('users');
    let userExists = (await collection.find({email: email}).limit(1).count()) > 0;
    db.close();
    return userExists;
}

хотя в идеале вы бы предпочли

async function userExistsInDB(email) {
    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}).limit(1).count();
        return userCount > 0;
    } finally {
        db.close();
    }
}
person Bergi    schedule 31.10.2015