Javascript 串联执行函数

Javascript 串联执行函数,javascript,node.js,connect,express,Javascript,Node.js,Connect,Express,首先。。。新年快乐 你能给我解释一下,这是如何工作的吗?我浏览了Connect(https://github.com/senchalabs/connect)源代码,但我不明白 我想自己写 app.get( '/', function(req, res, next) { // Set variable req.var = 'Happy new year!'; // Go to next function next(); }, func

首先。。。新年快乐

你能给我解释一下,这是如何工作的吗?我浏览了Connect(https://github.com/senchalabs/connect)源代码,但我不明白

我想自己写

app.get(
  '/',
  function(req, res, next) {
    // Set variable        
    req.var = 'Happy new year!';
    // Go to next function
    next();
  },
  function(req, res, next) {
    // Returns 'Happy new year!' 
    console.log(req.var); // <- HOW IS THIS POSSIBLE?
    // (...)
  }      
);
app.get(
'/',
功能(req、res、next){
//设置变量
req.var=‘新年快乐!’;
//转到下一个函数
next();
},
功能(req、res、next){
//返回“新年快乐!”

console.log(req.var);//似乎您提供的第一个函数参数首先被
get()
函数调用

调用时,将为调用提供3个参数。在调用中,
req
参数必须是可以为其分配属性的对象。您已为
var
属性分配了值,并为其指定了一个值
“新年快乐!”

您传递的下一个函数参数是通过调用
next()
参数来调用的,并且再次为该调用提供了3个参数。第一个参数显然与您在第一次调用中分配
var
属性的对象相同

因为它(显然)是同一个对象,所以您指定的属性仍然存在

下面是一个简单的例子:(打开控制台)


请注意,这是一个非常简化的示例,函数中的参数更少。我并没有将
var
更改为
msg
,因为
var
是一个保留字。

如果您愿意,可以尝试使用异步模块。它使事情更容易串联、并行或使用池运行


@Patrick如果我们有更多的函数呢?比如
get([fn1,fn2,fn3,…]);
?@Latanmos:在这种情况下,我可能会迭代
get()中的
参数
对象
函数。对于每个参数,我将创建一个新的
nxt
函数来调用下一个函数,将每个函数放在一个数组中。我将在一分钟内制作一个示例。@Latanmos:没关系。这是因为
For
循环不会为变量
I
创建一个新的作用域。这意味着当我们使用每个函数时最终运行数组中的hed(在for循环完成后),它们都将引用相同的
i
变量,该变量将设置为循环末尾的任何值。换句话说,在
for
循环内执行的任何代码都将使用当前值
i
,但执行延迟的任何代码(如这些函数)将引用
i
的最新值。而不是您期望的
0,1,2等。
在javascript中定义变量范围的唯一方法是在函数中。因此,我们创建
add\u fn
函数,将
i
的当前值传递给它,以便在该函数执行中,我们有一个局部变量
i
被推入
数组的函数可以引用。因此,如果有
4个
函数被赋予
.get()
,我们将有
4
调用
add\u fn
。第一个将被赋予值
0
,然后下一个
1
,然后
2
,依此类推。然后,被推送到数组中的函数有一个对该特定值的引用……此活动被称为创建
闭包
,因为我们使用的函数是数组中的shing包含对创建它(我们传递的func)的函数中存在的局部变量的引用。换句话说,现在数组中的函数已“关闭”
add\u fn
函数中的本地
i
变量。如果像我在中所做的那样更改
add\u fn
函数中的变量名,可能会更清楚一些。
// The main get() function. It has two function parameters.
function get(fn1, fn2) {
      // create an empty object that is passed as argument to both functions.
    var obj = {};
      // create a function that is passed to the first function, 
      //   which calls the second, passing it the "obj".
    var nxt = function() {
        fn2(obj); //When the first function calls this function, it fires the second.
    };
      // Call the first function, passing the "obj" and "nxt" as arguments.
    fn1(obj, nxt);
}

// Call get(), giving it two functions as parameters
get(
  function(req, next) {
      // the first function sets the req argument (which was the "obj" that was passed).
    req.msg = 'Happy new year';
      // the second function calls the next argument (which was the "nxt" function passed).
    next();
  }, 
  function(req) {
     // The second function was called by the first via "nxt",
     //   and was given the same object as the first function as the first parameter,
     //   so it still has the "msg" that you set on it.
    console.log(req.msg);
  }
);