在写代码时遇到一个问题。采用NodeJS + express + jqtpl + MySQL编写网页,NodeJS的部分代码如下:
感觉用NodeJS开发,要特别注意这一点,不能用以往同步的编程模型来设计和编码。
var mysql = require('mysql');
var conn = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'root',
database: 'test_db'
});
......
app.get('/some-page', function(req, res){
var options = {title: 'hello', data: ''};
conn.query('SELECT id FROM test_db.id;', function(err, rows, fields){
options.data = rows;
});
res.render('some-page', options);
});
......
文件some-page.html中的部分代码如下:
<ol>
{{each(i, entity) data}}
<li>${entity.id}</li>
{{/each}}
</ol>
我在表test_db.id里放了些数据,以为可以在<ol>中看到这些数据。结果让我很意外,<ol>中什么内容也没有。于是我加了两行输出:
app.get('/some-page', function(req, res){
var options = {title: 'hello', data: ''};
conn.query('SELECT id FROM test_db.id;', function(err, rows, fields){
options.data = rows;
console.log(1, options.data);
});
console.log(2, options.data);
res.render('some-page', options);
});
本以为1会在2之前输出,结果实际的情况是2先输出。想了一下,明白了。NodeJS采用的是异步(事件驱动/回调)的编程模型,conn.query没有像平时使用mysql_real_query那样阻塞在那里,而是直接执行下面的语句。
现在的想法是把data用AJAX发送到客户端,服务端负责渲染框架,数据的部分发送到客户端,让客户端来渲染。代码类似:
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = function(){
var html = '<ol>';
var json = eval('(' + ajax.responseText + ')');
for (var ent in json){
html += '<li>' + ent.id + '</li>';
}
html += '</ol>';
document.getElementById("data-div").innerHTML = html;
}
ajax.open();
ajax.send();
不过不知道性能如何。
感觉用NodeJS开发,要特别注意这一点,不能用以往同步的编程模型来设计和编码。