#mysql #json #node.js #angularjs #callback
#mysql #json #node.js #angularjs #обратный вызов
Вопрос:
Я использую node, angular и mysql, маршруты узлов будут возвращать json, который будет обработан angular, json возвращается при первом запросе к базе данных mysql с использованием модуля node-mysql, В приведенном ниже коде я не могу установить значение CreatedID
, но значение регистрируется должным образом в терминале. Я столкнулся с той же проблемой в 1-м запросе, но затем отсортировал ее в приведенном ниже коде, теперь не могу получить доступ к результатам вложенного запроса.
var mysql = require('node-mysql/node_modules/mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : "root",
password: "",
database:'designtaskmanager'
});
connection.connect();
var allDbCalls = function() {
var sendData = {};
var rowData = {};
var temp={};
var _this = this;
this.sendTask = function(callback) {
module.exports.taskData = rowData;
callback['success']();
};
this.getTask = function(callback) {
var strQuery = "select * from task";
connection.query( strQuery, function(err, rows){
if(err)
{
callback['failure']();
throw err;
}
else
{
//rowData = rows;
var tasks=[];
for (var i in rows)
{
var Title = rows[i].task_title;
var TaskDescription=rows[i].task_description;
var TaskCategory=rows[i].task_category;
var TaskID=rows[i].task_id;
var TaskStatus=rows[i].task_status;
var TaskStatusMessage
var CreatedBy;
var TaskCreationDate=rows[i].task_creation_date;
var _MS_PER_DAY = 1000 * 60 * 60 * 24;
var currentdate = new Date();
var ddd=dateDiffInDays(TaskCreationDate,currentdate);
function dateDiffInDays(a, b) {
// Discard the time and time-zone information.
var utc1 = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());
var utc2 = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate());
return Math.floor((utc2 - utc1) / _MS_PER_DAY);
}
if(TaskStatus==0)
{
TaskStatus="label-info";
TaskStatusMessage="Ongoing since";
}
else if(TaskStatus==1)
{
TaskStatus="label-default";
TaskStatusMessage="Paused since"
}
else if(TaskStatus==2)
{
TaskStatus="label-success";
TaskStatusMessage="Completed in"
}
//USER DETAILS QUERY
var crid=rows[i].task_created_by;
var creatorQuery = "select user_email from users where user_id like ?";
connection.query( creatorQuery,[crid], function(err, createdbyrows){
if(err)
{
callback['failure']();
throw err;
}
else
{
for(var j=0; j< createdbyrows.length;j )
{
CreatedBy=createdbyrows[0].user_email;
console.log(j);
}
console.log(CreatedBy);
}
});
var taskItem={"TaskID":TaskID,"TaskTitle":Title,"TaskDescription":TaskDescription,"TaskCategory":TaskCategory,"CreatedBy":CreatedBy,"TaskStatus":TaskStatus,"TaskStatusMessage":TaskStatusMessage,"DifferenceInDays":ddd};
tasks.push(taskItem);
}
rowData=tasks;
_this.sendTask(callback);
}
});
}
}
module.exports = function () {
var instance = new allDbCalls();
return instance;
};
Комментарии:
1. Вы также можете подумать об использовании ОБЪЕДИНЕНИЙ. Использование циклов для поиска большего количества данных во многих случаях будет менее эффективным. Например, ваш запрос будет
SELECT t.*, e.user_email FROM tasks t JOIN users u ON (u.user_id = t.task_created_by)
. Это даст вам все из таблицы tasks, плюс адрес электронной почты пользователя, который создал каждую задачу.
Ответ №1:
Причина, по которой вы видите это на консоли, но не в обратном вызове, заключается в неправильном понимании асинхронного программирования. Когда вы:
for(var i in rows) {}
На самом деле вы ставите в очередь все эти запросы одновременно, затем, сразу после попытки установить rowData в пустой массив:
rowData=tasks; // remember, none of the queries have finished yet
_this.sendTask(callback);
Таким образом, вы в значительной степени вызываете свой обратный вызов, когда tasks все еще является пустым массивом. Помните, вы не можете вызвать свой окончательный обратный вызов, пока не завершатся ВСЕ ваши вложенные запросы!
Чтобы выполнить это, вы можете захотеть взглянуть на библиотеку async: https://github.com/caolan/async#eachSeries
Это поможет вам достичь того, чего вы действительно хотите.
var async = require("async");
async.eachSeries(rows, function(row, cb) {
// Do each query here
// then call cb() when done, which tells the async library
// to "go to the next item in the array"
}, function(err) {
// This will get called when all of the single queries are finished
// Check err, then call your callback
_this.sendTask(callback);
});
Комментарии:
1. можете ли вы указать мне на базовый пример для mysql, который возвращает json для маршрута
2. Возможно, вы захотите проверить ORM, подобный sequelizejs.com/articles/express это сделает большую часть этого для вас (работа с Express, превращение строк в объекты и т.д.).