Я пытаюсь использовать меньшее количество обратных вызовов в своем коде, поэтому я думаю, что в решении, использующем async / await, но это не работает, экспресс-отправка просчитывает представление до завершения запроса.

Результаты запросов в порядке, но после рендера.

узел -v = 8.9.1

Код контроллера:

app.get('/admin', ensureLoggedIn('/login'), (req, res, next) => {

  app.infra.connectionFactory(async (err, connection) => {  

    const blogDAO = new app.infra.BlogDAO(connection);

    const emailCount = await blogDAO.countLeads((errDAO, results) => {
    if (errDAO) {
        return next(errDAO);
    }
    return results[0].leads;
    });

    const userDAO = new app.infra.UserDAO(connection);
    const subCount = await userDAO.countUsers((errDAO, results) => {
    if (errDAO) {
        return next(errDAO);
    }
    return results[0].users;
    });

    const postCount = 3;

    res.render('admin/index', { emailCount, subCount, postCount });
  });
});

Код DAO:

UserDAO.prototype.countUsers = function countUsers(callback) {
  this.connection.query('SELECT COUNT(token) AS users FROM users', callback);
};
0
clsechi 27 Фев 2018 в 07:17

3 ответа

Лучший ответ

Ключевое слово await заставляет JavaScript ждать, пока это обещание выполнится и вернет свой результат. Дополнительную информацию смотрите здесь.

Вам нужно изменить код на

Код DAO

UserDAO.prototype.countUsers = function countUsers() {
  return this.connection.query('SELECT COUNT(token) AS users FROM users');
};

Функция countUsers возвращает обещание.

Код контроллера

try {
    const result = await userDAO.countUsers();
    const subCount = result[0].leads; // Or anything that will work with result
} catch(err) {
    console.log(err); // Handle the error
}

Подождите, пока обещание не уляжется. Если это разрешится, результат будет в subCount и если отклонение или ошибка произойдет, это должно быть обработано блоком catch.

Надеюсь, это поможет.

0
Kishan Pradhan 27 Фев 2018 в 04:47

Лучший способ завершить запросы, по крайней мере, для меня, это использовать модуль async, так как вы упомянули, что хотите, чтобы запросы выполнялись до метода рендеринга.

Что оно делает? Запускает несколько функций с обратными вызовами и сохраняет результат в переменной. Не нужно вникать в обещания!

Я привел пример ниже.

const all= require('../Model/all'); // This is the model which I'm calling
const async=require('async');  // You need to install this one

exports.edit = async function(req, res){
    id=req.params.id;
    table=req.params.table;
    department_companies=[];
    first_query=[];
    second_query=[];

    async.parallel({
            record: async.apply(all.getRecord,table,id),
            first_query: async.apply(all.viewPrimaryKeys,"first_table"),  // viewPrimaryKeys has 2 params: Table name and Callback
            second_query: async.apply(all.viewPrimaryKeys,"second_table"),
        }
        ,function(err,results){
            res.render('team/edit', {
                id: id, 
                record: results["record"],
                first_query: results["first_query"],
                second_query: results["second_query"]
            });
        }
    );
}

Запустите async.parallel для всех функций, используя async.apply для каждой из этих функций, с res.render в выходной функции, надеюсь, это поможет!

0
Hoshang Charania 16 Окт 2018 в 22:32

Вы можете начать с использования библиотеки обещаний, такой как bluebird, и обещать вещи с помощью обратных вызовов.

http://bluebirdjs.com/docs/api/promise.promisifyall.html

Что-то вроде:

const Promise = require('bluebird');

app.get('/admin', ensureLoggedIn('/login'), (req, res, next) => {

  app.infra.connectionFactory(async (err, connection) => {

    const blogDAO = Promise.promisifyAll(new app.infra.BlogDAO(connection))
    const results = await blogDAO.countLeadsAsync();
    const emailCount = results[0].leads;
....

Должен сделать это.

0
AnC 27 Фев 2018 в 04:51