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