[英]Node.js extract value from callback function
I have a server file with a switch using the URL to display appropriate content. 我有一个服务器文件,其中有一个使用URL来显示适当内容的开关。 One of the cases is /users which should display a JSON string of a certain table.
一种情况是/ users,它应该显示某个表的JSON字符串。 This is returned from a mysql file.
这是从mysql文件返回的。
server.js 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 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));
});
};
The console.log(users)
in server.js displays the JSON string fine, but I cannot figure out how to get the value out of the callback and into the response variable. server.js中的
console.log(users)
可以很好地显示JSON字符串,但是我无法弄清楚如何从回调中获取值并放入响应变量中。
Any ideas will be greatly appreciated. 任何想法将不胜感激。
The way you could extract the value out of the callback is to assign that value to a variable out of the callback's scope, but I don't recommend you to do that since you would end up with lots of global variables, besides you don't know when the variable will be assigned. 您可以从回调中提取值的方法是将该值分配给回调范围之外的变量,但是我不建议您这样做,因为您最终会得到很多全局变量,除了不知道何时分配变量。 Try this and see what happens so you get some insight with how callbacks and node.js works:
尝试一下,看看会发生什么,以便您对回调和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
}
The way I would go is something like this: 我要走的路是这样的:
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 + '.')
You do not need to serialize the mysql returned rows
to use it. 您无需序列化mysql返回的
rows
即可使用它。 Either you can process it within getUsers
, or return it back to the controller. 您可以在
getUsers
中对其进行处理,也可以将其返回给控制器。 If you return it, change code to: 如果返回,请将代码更改为:
exports.getUsers = function(callback) {
connection.query('SELECT * FROM users;', function (error, rows, fields) {
callback(rows);
});
};
Now within the server.js
file, you can process the returned rows, like: 现在,在
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;
You can process 您可以处理
you can't do it like this. 你不能这样做。 the problem is easy.
问题很容易。 let's talk about it: function
getUsers
is an asynchronous. 让我们来谈谈:
getUsers
函数是异步的。 so the code follow runs like this: 因此代码遵循如下运行:
case '/users':
var response
require('./mysql').getUsers(function(users) {
console.log(users)
response = users
})
return response
break
first, run require('./mysql').getUser()
, then it will do return response
directly, then break
. 首先,运行
require('./mysql').getUser()
,然后它将直接return response
,然后break
。 when the getUser
function is finished, it will run 当
getUser
函数完成时,它将运行
function(users) {
console.log(users)
response = users
})
so, a rule you need to follow: once you use asynchronous, the other function have to be asynchronous. 因此,您需要遵循一条规则:一旦使用异步,其他功能就必须异步。 i wonder you can modify like follow:
我不知道您可以修改如下:
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 + '.')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.