Node.js从callback函数中提取值

我有一个服务器文件与开关使用URL来显示适当的内容。 其中一种情况是/用户应该显示某个表的JSONstring。 这是从一个MySQL文件返回。

server.js

var http = require('http') var url = require('url') var port = 8080 function onRequest(request, response) { var pathname = url.parse(request.url).pathname console.log('Request for ' + pathname + ' received.') response.writeHead(200, {'Content-Type': 'text/html'}) response.write(run(pathname)) response.end() } function run(pathname) { switch(pathname) { case '/': response = 'Welcome to my little test' break case '/time': response = 'The time is ' + new Date().toLocaleTimeString() break case '/users': var response require('./mysql').getUsers(function(users) { console.log(users) response = users }) return response break default: response = 'Unable to locate the requested page' } return response } http.createServer(onRequest).listen(port) console.log('Server started on port ' + port + '.') 

mysql.js

 var mysql = require('mysql') var connection = mysql.createConnection({ user: "root", password: "password", database: "main" }) exports.getUsers = function(callback) { connection.query('SELECT * FROM users;', function (error, rows, fields) { callback(JSON.stringify(rows)); }); }; 

server.js中的console.log(users)显示JSONstring正常,但我无法弄清楚如何从callback中获取值并将其转换为响应variables。

任何想法将不胜感激。

您可以从callback中提取值的方式是将该值分配给callback范围外的variables,但我不build议您这样做,因为您最终会得到很多全局variables,除此之外,知道什么时候variables将被分配。 试试看看会发生什么事情,以便了解callbacks和node.js是如何工作的:

 function run(pathname) { switch(pathname) { case '/': response = 'Welcome to my little test' break case '/time': response = 'The time is ' + new Date().toLocaleTimeString() break case '/users': var response var out_of_callback_users require('./mysql').getUsers(function(users) { out_of_callback_users = users console.log("In the callback") console.log(users) response = users }) console.log("After require"); console.log(out_of_callback_users) //Users have not been assigned yet setTimeout(function(){ console.log("In the timeout") console.log(out_of_callback_users) },5000) //After 5 secs the query has been completed and users have been assigned. return response break default: response = 'Unable to locate the requested page' } return response } 

我会走的方式是这样的:

 function onRequest(request, response) { var pathname = url.parse(request.url).pathname console.log('Request for ' + pathname + ' received.') response.writeHead(200, {'Content-Type': 'text/html'}) run(pathname, function(response){ response.write(response) response.end() }) } function run(pathname,cb) { switch(pathname) { case '/': cb('Welcome to my little test'); break; case '/time': cb('The time is ' + new Date().toLocaleTimeString()); break; case '/users': require('./mysql').getUsers(function(users) { console.log(users); cb(users); }) break; default: cb('Unable to locate the requested page'); } return; } http.createServer(onRequest).listen(port) console.log('Server started on port ' + port + '.') 

你不能这样做。 问题很简单。 让我们来谈谈它:function getUsers是一个asynchronous的。 所以代码如下运行:

  case '/users': var response require('./mysql').getUsers(function(users) { console.log(users) response = users }) return response break 

首先运行require('./mysql').getUser() ,然后直接return response ,然后break 。 当getUser函数完成时,它将运行

  function(users) { console.log(users) response = users }) 

所以,你需要遵循的规则是:一旦你使用asynchronous,其他function必须是asynchronous的。 我不知道你可以修改如下:

 function onRequest(request, response) { var pathname = url.parse(request.url).pathname console.log('Request for ' + pathname + ' received.') response.writeHead(200, {'Content-Type': 'text/html'}) run(pathname, function(res){ response.write(res)}) //changed response.end() } function run(pathname, callback) { switch(pathname) { case '/': callback('Welcome to my little test') break case '/time': callback('The time is ' + new Date().toLocaleTimeString()) break case '/users': var response require('./mysql').getUsers(function(users) { console.log(users) callback(users) # changed }) break default: callback('Unable to locate the requested page') } } http.createServer(onRequest).listen(port) console.log('Server started on port ' + port + '.') 

你不需要序列化mysql返回的rows来使用它。 您可以在getUsers处理它,也可以将其返回给控制器。 如果您返回,请将代码更改为:

 exports.getUsers = function(callback) { connection.query('SELECT * FROM users;', function (error, rows, fields) { callback(rows); }); }; 

现在在server.js文件中,您可以处理返回的行,如:

 case '/users': var response = '' require('./mysql').getUsers(function(users) { for (var i in users) { var user = users[i]; var userId = user.id; var userName = user.user_name; response += "User - ID: "+userId+" Name: "+userName+"\n"; } }) return response; break; 

你可以处理