Визуализация моего файла ejs после завершения моего запроса

#javascript #sql #node.js #asynchronous

#javascript #sql #node.js #асинхронный

Вопрос:

Я хочу убедиться, что мое приложение будет вызывать res.render(‘pages / students’ …) только после завершения всех моих запросов, и я получу все необходимые данные. Однако я совершенно не знаю, как это сделать, и у меня возникают проблемы с применением всех примеров, которые я вижу в Интернете, к моему коду. Может кто-нибудь помочь мне? (Есть два кон.запрос (…) в моем маршруте. Я хочу визуализировать (‘страницы / учащиеся’ …) только после обоих этих действий.запрос полностью завершен. Поэтому я использую async для выполнения всех моих запросов до завершения. Однако теперь по какой-то причине моя страница не загружается.

 app.get('/admin', function(req, res) {
    var sql =
        'SELECT events.id, name, description, MONTHNAME(start_time) AS month, DAY(start_time) AS day, '  
        "YEAR(start_time) AS year, DATE_FORMAT(start_time, '%h:%i%p') AS start_time, HOUR(start_time) AS start_hour, MINUTE(start_time) AS start_minute, "  
        "DATE_FORMAT(end_time, '%h:%i%p') AS end_time, HOUR(end_time) AS end_hour, MINUTE(end_time) AS end_minute, location, max_capacity, hidden_sign_up, "  
        'eventleaders.first_name AS eventLeader FROM events LEFT JOIN eventleaders_has_events ON events.id = eventleaders_has_events.events_id '  
        'LEFT JOIN eventleaders ON eventleaders_has_events.eventleaders_id = eventleaders.id;';
    var events = {};
    con.query(sql, function(err, results) {
        if (err) throw err;
        async.forEachOf(results, function(result, key, callback) {
            var date = result.month   ' '   result.day   ', '   result.year;
            var other = 'N/A';
            if (result.other !== null) {
                other = result.other;
            }
            if (typeof events[date] === 'undefined') {
                events[date] = {};
            }
            var studentAttendees = {};
            var sql =
                'SELECT * FROM students INNER JOIN students_has_events ON students.id = students_has_events.Students_id '  
                'WHERE students_has_events.Events_id = ?';
            var values = [result.id];
            con.query(sql, values, function(err, results1) {
                if (err) throw err;
                async.forEachOf(results1, function(result1, key, callback) {
                    studentAttendees[result1.first_name   ' '   result1.last_name] = {
                        netID: result1.netID,
                        phoneNumber: result1.phone,
                        email: result1.email
                    };
                });
                //still need to get the event leader attendees
                events[date][result.name] = {
                    startTime: result.start_time,
                    location: result.location,
                    endTime: result.end_time,
                    description: result.description,
                    eventLeader: result.eventLeader,
                    numberRegistered: result.hidden_sign_up,
                    maxCapacity: result.max_capacity,
                    poster: '/images/sample.jpg',
                    other: other,
                    attendees: studentAttendees
                };
            });
        });
    });
});
  

Комментарии:

1. Переместить res.render сразу после событий [дата][currRecord.name ] назначение

2. Вы можете использовать async await, чтобы сначала дождаться завершения запроса, а затем отобразить шаблон

3. Что вы используете в качестве зависимости от NPM для доступа к базе данных?

Ответ №1:

Два варианта:

 app.get('/admin', function(req, res) {
    ...
    con.query(sql, function(err, result) {
        ...
            con.query(sql, values, function(err, result) {
                events[date][currRecord.name] = {
                    ...
                };
                // put it here
                console.log(events);
                res.render('pages/admin', {
                  events: events
                });
            });
        }
    });
});
  

Или используйте Promise версию mysql

 const mysql = require('mysql2/promise');

// make this async
app.get('/admin', async function(req, res) {
  try {
    ...
    // might want to move this elsewhere inside async function
    const con = await mysql.createConnection({host:'localhost', user: 'root', database: 'test'});
    const result1 = await con.query(sql);
    // run your logic preferably inside map
    // result2 is an array of Promises
    const result2 = result1.map((result, index) => {
      var currRecord = result[index];
      var date =
          currRecord.month   ' '   currRecord.day   ', '   currRecord.year;
      var other = 'N/A';
      if (currRecord.other !== null) {
        console.log('here');
        other = currRecord.other;
      }
      if (typeof events[date] === 'undefined') {
        events[date] = {};
      }
      //get all the student attendees of this event
      var studentAttendees = {};
      var sql =
          'SELECT * FROM students INNER JOIN students_has_events ON students.id = students_has_events.Students_id '  
          'WHERE students_has_events.Events_id = ?';
      var values = [currRecord.id];
      return con.query(sql)
    })
    // result3 is an array of results. If your results is also an array, the structure might look lik [[student], [student]] etc.
    const result3 = await Promise.all(result2);
    // run your logic to get events
    console.log(events);
    res.render('pages/admin', {
        events: events
    }); 
  } catch (e) {
    // handle error
    console.error(e)
  }
});