Как использовать асинхронный вызов ReadFile, который преобразует значение в условии if (Экспресс)

#node.js #express

#node.js #выразить

Вопрос:

Я создаю конечную точку Express, где я проверяю, есть ли имя пользователя / пароль в моей базе данных (json-файл)

 router.post('/login', (req, res) => {
    let userData = req.body;
    if (validateEmailAndPassword(userData.username, userData.password) {
        res.send(userData);
    } else {
        res.status(401).send({ error: "Username/Password combination is incorrect." });
    }
})

const validateEmailAndPassword = (username, password) => {
    let validCreds = false;
    fs.readFile('db/users.json', 'utf8', (err, data) => {
        if (data) {
            const stream = JSON.parse(data);
            const usersFound = stream.filter(info => {
            if (info.username === username amp;amp; info.password ===password) { return true; }
            })
        if (usersFound.length >= 1) { validCreds = true; }
        return validCreds;

        } else {
            throw Error(err);
        }
    })
}
  

‘validateEmailAndPassword(userData.username, userData.password)’ в строке 3 первого блока кода возвращает ‘undefined’ в условии if, поскольку оно асинхронное.

Каков наилучший способ синхронно разрешить ‘validateEmailAndPassword(userData.username, userData.password)’, чтобы я получал значение true / false без использования readFileSync?

Заранее спасибо!

Ответ №1:

используйте async await и promises

 router.post('/login', async(req, res) => {
    let userData = req.body;
    if (await validateEmailAndPassword(userData.username, userData.password)) {
        res.send(userData);
    } else {
        res.status(401).send({ error: "Username/Password combination is incorrect." });
    }
})

const validateEmailAndPassword = (username, password) => {
    let validCreds = false;
    return new Promise(resolve => {
    fs.readFile('db/users.json', 'utf8', (err, data) => {
        if (data) {
            const stream = JSON.parse(data);
            const usersFound = stream.filter(info => {
            if (info.username === username amp;amp; info.password ===password) { return true; }
            })
        if (usersFound.length >= 1) { validCreds = true; }
        resolve(validCreds);
        return validCreds;

        } else {
            throw Error(err);

        }
    })
    })
}
  

tada

Ответ №2:

Подробнее об ответе @Estradiaz…

Похоже, вы хотите использовать его синхронно, поэтому вы могли бы просто сделать его синхронным вместо того, чтобы использовать его асинхронно и ожидать его:

ReadFile -> readFileSync

 const validateEmailAndPassword = (username, password) => {
    let validCreds = false;
    var data = fs.readFileSync('db/users.json', 'utf8');
    if (data) {
        const stream = JSON.parse(data);
        const usersFound = stream.filter(info => {
            if (info.username === username amp;amp; info.password === password)
                return true;
        });

        if (usersFound.length >= 1)
            validCreds = true;

        return validCreds;

    } else {
        throw Error(err);
    }
}