Javascript 串联执行函数
首先。。。新年快乐 你能给我解释一下,这是如何工作的吗?我浏览了Connect(https://github.com/senchalabs/connect)源代码,但我不明白 我想自己写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
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);
}
);