使用Node.js处理多个MySQL查询

我是事件/callback风格编程和NodeJS的新手。 我试图实现一个小的http服务器,它使用node-mysql模块来提供ddbb数据。

我的问题来自查询结构。 由于经常有查询需要运行以前的查询结果,因此我无法同时运行所有这些查询(asynchronous),而且我不得不等待一些结果。

我的第一个方法是同时运行所有的非依赖查询,然后循环,直到所有人都设置了一个标志,说我已经完成了,所以我可以继续依赖(同步)的,但我不知道这是否是正确的方法。

像这样的东西:

function x(){ var result_for_asynch_query_1 = null var result_for_asynch_query_2 = null mainLoop(){ // call non-dependant query 1 // call non-dependant query 2 // loop until vars are != null // continue with queries that require data from the first ones } } //for each browser request httpServer{ call_to_x(); }.listen(); 

这样我可以节省一些时间在最后的结果,因为我不等待所有的反应,而是以一种连续的方式,而只是最长的一个。

有没有一个共同的方法来做到这一点? 我没有遵循的任何devise模式?

尝试其他方式思考(有很好的介绍asynchronousstreamhowtonode.org )

 var db = get_link_or_pool(); do_queries( callback ) { db.query(sql1, function(err, res1) { if (err) { callback(err); return; } // use res1 ... db.query(sql2, function(err, res2) { if (err) { callback(err); return; } callback(null, res2); // think 'return' } }); } request_handler(req) { do_queries( function(err, result) { if(err) report_error(err); else write_result(req, result); }); } 

人们应该避免厄运的金字塔:

 var express = require('express'); var Q = require('Q'); var app = express(); app.get('/',function(req,res){ var mysql = require('mysql'); var connection = mysql.createConnection({ host : 'localhost', user : 'root', password : '' }); connection.connect(); function doQuery1(){ var defered = Q.defer(); connection.query('SELECT 1 AS solution',defered.makeNodeResolver()); return defered.promise; } function doQuery2(){ var defered = Q.defer(); connection.query('SELECT 2 AS solution',defered.makeNodeResolver()); return defered.promise; } Q.all([doQuery1(),doQuery2()]).then(function(results){ res.send(JSON.stringify(results[0][0][0].solution+results[1][0][0].solution)); // Hint : your third query would go here }); connection.end(); }); app.listen(80); console.log('Listening on port 80'); 

此示例显示了一个依赖于2个独立计算值的结果。 在doQuery1和doQuery2中查询这些值中的每一个。 它们按顺序执行,但是是asynchronous执行的。

接下来你可以看到Q.all(...基本上调用成功的“then”callback,在callback中,计算完成。

使用promise(细节: Github Q:允许使用Javascript和维基百科 )允许您的代码更清洁,分离计算和处理结果,并将事物放在一边。

看看添加“doQuery3”作为计算的先决条件是多么容易!

并在示例代码中包含“package.json”:

 { "name": "hello-world", "description": "hello world test app", "version": "0.0.1", "private": true, "dependencies": { "express": "3.2.0", "q": "0.9.3", "mysql":"2.0.0-alpha7" } } 

另一个解决scheme是连接所有语句,每个语句以分号结尾。 例如,要从多个表中进行select,您可以使用此查询:

var sql = 'select * from user; select * from admin;'

然后,您只能使用一个连接来执行多个语句:

var connection = mysql.createConnection({multipleStatements: true}) connection.query(sql)

注意:默认情况下禁用多个语句以防止SQL注入。 确保正确地转义所有值(请参阅文档) 。

我发现以下非常有用的解决这个问题:

取自http://book.mixu.net/node/ch7.html – 这里有很多其他很棒的例子!

 function async(arg, callback) { console.log('do something with \''+arg+'\', return 1 sec later'); //replace setTimeout with database query setTimeout(function() { callback(arg * 2); }, 1000); } // Final task (return data / perform further operations) function final() { console.log('Done', results); } // A simple async series: var items = [ 1, 2, 3, 4, 5, 6 ]; var results = []; function series(item) { if(item) { async( item, function(result) { results.push(result); return series(items.shift()); }); } else { return final(); } } series(items.shift()); 

“取一组项目,并用第一个项目调用序列控制stream程函数,系列启动一个async()操作,并将callback传递给它,callback将结果推入结果数组,然后调用下一个系列item数组中的item,当items数组为空时,我们调用final()函数。 (来自http://book.mixu.net/node/ch7.html