Node.js 다중 쿼리 결과 처리 방법
조회수 4862회
node.js, express 를 이용 중 입니다.
mysql 연동해서 db 결과를 변수 값에 넣고, render 쪽에 보내주려고 합니다.
그런데 전역변수를 시도하려 global.score 로 표기까지 해봤는데, 결과는 아래와 같이 쿼리 결과는 하나도 없이 나와서 질문드립니다.
node.js 는 한 3일정도 밖에 접하지 못해서 콜백 사용법이 미숙하여 질문드립니다. 어떻게 쿼리 결과를 전부 불러올 수 있는지 알려주시길 부탁드립니다.
[결과]
)]}', {"scoredboard" : [}
[소스코드]
var express = require('express');
var router = express.Router();
//db - mysql
var mysql = require('mysql');
var dbconfig = require('../dbconfig.js');
var db = dbconfig.database;
var connection=mysql.createConnection({
host:db.host,
port:db.port,
user:db.user,
password:db.password,
database:db.database
});
/* GET home page. */
router.get('/', function(req, res, next) {
/*
{"scoreboard": [{"tid": 68, "position": 1, "score": 200, "name": "A", "history": [{"score": 200, "when": "2016-04-01T17:17:42+00:00"}, {"score": 150, "when": "2016-03-28T17:19:04+00:00"}, {"score": 50, "when": "2016-03-27T17:24:33+00:00"}, {"score": 10, "when": "2016-03-23T17:32:48+00:00"}, {"score": 5, "when": "2016-03-22T17:24:33+00:00"}]}, {"tid": 3, "position": 2, "score": 0, "name": "B", "history": [{"score": 0, "when": "2016-03-23T17:18:26+00:00"}]}
*/
global.scoreboard = '{\"scoredboard\" : [';
var position = connection.query('select tid, score, name from teams order by (score+0);', function(err, rows_tid)
{
if(err)
{
console.error(err);
throws(err);
}
else
{
for(var i in rows_tid)
{
global.scoreboard = global.scoreboard + '{\"tid\": ' + rows_tid[i].tid + ', \"position\": ' + i + ', \"score\": ' + rows_tid[i].score + ', \"name\": \"' + rows_tid[i].name + '\", \"history\": [';
var query = connection.query('select score,DATE_FORMAT(wh, \'%Y-%m-%dT%T\') as wh from scoreboard where tid = ? order by wh',rows_tid[i].tid, function(err, rows)
{
if(err)
{
console.error(err);
throws(err);
}
else
{
for(var j in rows)
{
global.scoreboard = global.scoreboard + '{\"score\": ' + rows[j].score + ', \"when\": ' + rows[j].wh + '}';
if(j != rows.length-1)
{
global.scoreboard = global.scoreboard + ', ';
};
};
};
});
global.scoreboard = global.scoreboard + ']}';
if (i != rows_tid.length-1)
{
global.scoreboard = global.scoreboard + ', ';
}
};
};
});
global.scoreboard = global.scoreboard + '}';
res.render('scoreboard', {scoreboard:global.scoreboard});
});
module.exports = router;
-
(•́ ✖ •̀)
알 수 없는 사용자
1 답변
-
위 코드에서 빈 결과가 나오는 이유는
res.render
함수가 호출되는 시점에global.scoreboard
변수가 아직 준비되지 않았기 때문입니다.router.get
으로 입력된 요청은res.render
함수가 호출되는 동시에 종료됩니다.위 코드에 문제는
connectiion.query
의 결과를 기다리지 않고res.render
함수를 호출하기 때문입니다.connectiion.query
는 비동기 함수이기 때문에 해당 라인에서 코드가 멈춰서 결과를 기다리지 않고 계속 다음 라인으로 진행됩니다. 이후 실행 결과는 callback 함수를 통해 전달됩니다.따라서 문제를 해결하려면
connection.query
함수로 전달되는 callback 함수(function(err, rows_tid) 안쪽에서 전달된 쿼리 결과(rows_tid)를 사용해서res.render
함수를 호출해 줘야 합니다.위 이야기가 다 이해 되셨다면 문제는 모두 해결된 셈입니다.
위 코드에서는 추가적으로 약간 더 복잡한 부분이 있는데
connection.query
가 중첩되서 사용된 점입니다. 이런 부분은 손으로 직접 짜셔서 해결하실 수도 있지만 보통 async모듈이나 promise등을 이용해서 해결합니다.Node.js에서 가장 확실한 비동기 해결 방법은 코루틴을 사용하는 것인데 위 모듈 사용에 익숙해 지시면 한번 활용해 보시기를 추천 드립니다.
p.s: 비동기 문제를 해결하는데 전역변수는 필요하지 않습니다.
-
(•́ ✖ •̀)
알 수 없는 사용자 -
(•́ ✖ •̀)
알 수 없는 사용자 - 〉
- 감사합니다. 검색중에 async 모듈은 본적있었는데 모듈을 또 사용해야하나 하고 코드를 위처럼 짜봤는데... 비동기를 생각하지 못했네요. Async 를 사용해 보도록 하겠습니다. :) 알 수 없는 사용자 2016.4.11 08:42
-
댓글 입력