@yakovenkodenis
JavaScript, Node.js, React, PostgreSQL

Как вытащить значение переменной из вложенного await вызова async функции в ES7?

Я пытаюсь получить булевое значение из async функции, которая имеет в себе вложенную анонимную async функцию. Наверное, в коде будет понятнее:

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


Сама функция находится внутри класса, в котором есть еще одна функция, которая вызывает userExistsInDB:

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


Если я запускаю функцию getValidationErrors, то получаю на консоль следующий вывод:

OUTSIDE:
undefined
ANOTHER FUNC:
undefined
INSIDE:
true


хотя ожидается, что, при использовании await, первым выведется INSIDE: true

По сути, мне просто нужно достать значение переменной userExists из вложенного асинхронного вызова в функции userExistsInDB() и вернуть его. Но, почему-то не могу понять, что делаю не так.

Надеюсь, мне кто-нибудь сможет помочь
  • Вопрос задан
  • 1124 просмотра
Решения вопроса 1
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
я не 100% не уверен но... из того что вы написали:

returns Promise if no callback passed


вам надо убрать колбэк. По поводу обработки ошибок из спецификации async-functions мы должны переписать функцию так:

async userExistsInDB(email) {
    let userExists; 
    try {
         const db = await MongoClient.connect('mongodb://127.0.0.1:27017/notificator');
    } catch (err) {
         throw err; // тут у вас никакой обработки ошибок небыло... можно и без try/catch тогда
    }

    const 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;
}


код в дальнейшем можно еще упростить. Суть в том что при использовании await нет смысла в колбэках. Все происходит синхронно (с точки зрения потока управления, блокировок конечно же не будет).
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@yakovenkodenis Автор вопроса
JavaScript, Node.js, React, PostgreSQL
Получилось вот так в итоге:

async 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();
        }
    }
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы