nodejs express: store parameters in variable
我仍然是nodejs的新手,仍然不确定如何访问函数中的变量并调用变量。
检查几个链接:但我真的很困惑。 请帮忙!
Node.JS:如何将变量传递给异步回调?
我们如何从node.js中的回调函数中访问变量?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | var express = require('express'); var app = express(); var router = express.Router(); var https = require('https').createServer( ssl_options, app); var io = require('socket.io')( https ); **var user_id; var room_id;** router.use(function(req, res, next) { next(); }); app.use('/chat',router); router.route( '/chat/:user_id/:room_id' ) .get(function(req,res){ res.sendFile( __dirname + '/index.html' ); user_id = req.param('user_id'); room_id = req.param('room_id'); }); https.listen(3000); io.on('connection', function(socket){ **console.log ( user_id ); console.log ( room_id );** }); |
not sure how to access a variable in a function and call the variable back.
Ok.
以下是一些规则:
1.函数内声明的变量是函数的* local *。
以下是函数本地的含义示例:
1 2 3 4 5 6 | function do_stuff() { var x = 10; } do_stuff(); console.log(x); |
结果,行
1 | ReferenceError: x is not defined |
在第二个链接上提出问题的人未能理解一旦函数完成执行就会破坏局部变量,因此在声明username变量的匿名函数之外的任何地方都无法访问其代码中的username变量。
另一方面,如果你没有用var声明变量,那么javascript会创建一个全局变量:
1 2 3 4 5 6 | function do_stuff() { x = 10; } do_stuff(); console.log(x); //=>10 |
这相当于写作:
1 2 3 4 5 6 7 8 | var x; function do_stuff() { x = 10; } do_stuff(); console.log(x); //=>10 |
对于函数来说,操作函数外部变量的值通常被认为是不好的做法。您应该更喜欢以下内容:
1 2 3 4 5 | function do_stuff() { return 10; } var x = do_stuff(); |
在你的情况下,express是一个将调用你的匿名函数,并表达只丢弃任何返回值。据推测,express表达式是这样的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | function express_get(func) { console.log("express_get is executing"); requ = {greeting: 'hello'}; resp = {}; func(requ, resp); //Anything returned by func is not captured in a variable } //Here is an attempt to call express_get() and return //the data rather than setting a global variable: express_get(function(requ, resp) { console.log("my callback is executing"); console.log(requ); return {user_id: 1, room_id: 'A'}; }); --output:-- express_get is executing my callback is executing { greeting: 'hello' } |
因为express正在调用您的请求处理函数,并且因为express只丢弃任何返回值,所以无法访问从请求处理函数返回的值。
也许你正在以错误的方式思考这个问题?而不是试图弄清楚如何将请求数据输入到io.on('connect')代码中,您应该考虑如何在路由处理函数中获取io.on('connect')代码。如果你这样做会发生什么:
1 2 3 4 5 6 7 8 9 10 11 | router.route(...).get(function(req,res){ user_id = req.param('user_id'); room_id = req.param('room_id'); io.on('connection', function(socket){ console.log ( user_id ); console.log ( room_id ); }); }); |
根据本答案中讨论的所有规则,您应该尝试确定:
函数的参数变量也是函数的局部变量。
这是一个例子:
1 2 3 4 5 6 | function do_stuff(x) { console.log(x); //=>hello } do_stuff("hello"); console.log(x); //=>ReferenceError: x is not defined |
因此,在函数执行之前x不存在,并且当函数完成执行时x不再存在。
3.在for循环中声明的变量不是for循环的本地变量。
这是一个例子:
1 2 3 4 5 6 7 8 9 10 | function do_stuff() { for (var x=0; x < 10; ++x) { console.log(x); } console.log(x) //=>10 } do_stuff(); |
您可以等效地(并且更清楚地)编写上面的函数,如下所示:
1 2 3 4 5 6 7 8 9 10 11 | function do_stuff() { var x; for (x=0; x < 10; ++x) { console.log(x); } console.log(x) //=> 10 } do_stuff(); |
4.函数内部的代码可以在函数*定义*时看到函数外部周围范围内存在的变量。
这是一个例子:
1 2 3 4 5 6 7 | var x = 10; function do_stuff() { console.log(x); } do_stuff(); //=>10 |
很简单。周围范围意味着:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | //First line of program ^ | | part of do_stuff() surrounding scope | v ------------------------+ function do_stuff() { | //Do stuff | } | ------------------------+ ^ | part of do_stuff() surrounding scope | v ---------------------------+ function other_func() { | | | //Do other stuff | | } | ---------------------------+ ^ | part of do_stuff surrounding scope | v //Last line of program |
请注意,other_func中的代码区域不是do_stuff周围范围的一部分,因此do_stuff中的代码无法查看在other_func中声明的变量。
使用嵌套函数,周围的范围如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | ^ part of inner's surrounding scope | | function outer() { ^ | part of inner's surrounding scope | v ----------------------+ function inner() { | | } | ----------------------+ ^ | part of inner's surrounding scope v --------------------------+ function other_inner { | | } | --------------------------+ ^ | part of inner's surrounding scope | V } | | V part of inner's surrounding scope |
这是一个例子:
1 2 3 4 5 6 7 8 9 10 11 12 | var x = 10; function outer() { function inner() { console.log(x); } inner(); } outer(); //=>10 |
对于定义为函数参数的匿名函数,例如:
1 | some_func(10, 20, function(req, resp) {.....}); |
这几乎与写这个:
1 2 3 4 5 | function request_handler(req, resp) { //Do stuff } some_func(10, 20, requestHandler); |
您可以使用上面的图表找出request_handler函数的周围范围。
在计算机科学术语中,javascript函数被称为闭包,并且javascript函数被称为关闭在定义函数时存在的周围范围中的变量。如果你正在阅读一些声明某些函数是闭包的东西,你可以自言自语:"当函数执行时,它可以看到在定义函数时存在的周围范围内的变量。"
这是一个更复杂的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | function outer() { var x = 10; function inner() { console.log(x); } return inner; } func = outer(); //outer() has finished executing here. func(); |
从规则1开始,您可能希望在outer()完成后执行x将被销毁,因此当inner()通过func()执行时,您将得到一个未定义的错误。但事实并非如此。尽管通常在外部()完成执行时x会被破坏,但inner()仍然可以看到x。当内部被定义时,inner()被称为关闭周围范围中存在的变量。
这是另一个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | function outer() { var x = 10; function inner() { console.log(x); } return inner; } func = outer(); //outer() has finished executing here. var x = 20; //New code func(); |
那里的输出是什么? 20?不。 inner()函数在内部()定义时看到周围范围内的变量 - 而不是内部执行时周围范围内的变量。
最后一个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | function outer() { var funcs = []; for(var x=0; x < 10; ++x) { function inner() { console.log(x); } funcs.push(inner); } return funcs; } ten_funcs = outer(); for(var y=0; y < 10; ++y) { ten_funcs[y](); } |
您认为输出会是什么?事实证明,每个ten_funcs输出10.这表明函数关闭变量 - 而不是值。我们知道我们可以像这样重写外部:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | function outer() { var funcs = []; var x; for(x=0; x < 10; ++x) { function inner() { console.log(x); } funcs.push(inner); } return funcs; } |
所以每个ten_func都看到相同的x变量。定义函数后,可以在周围范围内看到的x变量被赋予一个新值,然后当每个ten_funcs执行时,它可以看到变量x,分配给x的最后一个值是10。谁在你的第一个链接问这个问题,对变量作用域的这个方面以及函数内部的代码可以看到哪些变量感到困惑。
唯一需要解释的是"隐藏":
1 2 3 4 5 6 7 8 | var x = 20; function do_stuff() { var x = 10; console.log(x); } do_stuff(); //=>10 |
这是规则4的一个例外。在函数内部,如果声明一个与函数周围范围内的变量同名的变量,javascript会创建一个新的局部变量,该变量将变量隐藏在周围的范围内。
好。