Javascript函数带有一个具有函数的参数?

时间:2012-08-30 12:55:38

标签: javascript node.js

请向我解释这是如何运作的。我是nodejs的新手,他们设置代码的方式让我理解起来非常复杂..

我把我不理解的代码分成了几个小片段。您可以在下面找到完整的代码。

callback(function() {
  results.push(Array.prototype.slice.call(arguments));
  next();
});

我不明白上面的代码片段。似乎这个匿名函数成为系列函数的下一个参数? anon函数参数中的代码是否会执行?

function(next) { async(1, next); }

哪个先执行?系列函数中的异步函数执行还是下一个参数执行?

这里我附上了完整的代码:

function series(callbacks, last) {
  var results = [];
  function next() {
    var callback = callbacks.shift();
    if(callback) {
      callback(function() {
        results.push(Array.prototype.slice.call(arguments));
        next();
      });
    } else {
      last(results);
    }
  }
  next();
}

function async(arg, callback) {
  var delay = Math.floor(Math.random() * 5 + 1) * 100;
  console.log('async with \''+arg+'\', return in '+delay+' ms');
  setTimeout(function() {
    callback(arg*2);
  }, delay);
}

function final(results) {
  console.log('Done', results);
}

series([
  function(next) { async(1, next); },
  function(next) { async(2, next); },
  function(next) { async(3, next); },
  function(next) { async(4, next); },
  function(next) { async(5, next); },
  function(next) { async(6, next); }
], final);

2 个答案:

答案 0 :(得分:3)

首先,要知道在JavaScript中,函数可以作为参数传递给其他函数。这与传递从另一个函数返回的值非常不同。举个简单的例子:

function A() {
    alert("In A"); 
}

function B(fn) {
    alert("In B");
    fn(); 
}

B(A);   // alerts "In B", then "In A".

B(A()); // alerts "In A", then "In B", 
        // (then errors because the return value from A is undefined, 
        // and thus cannot be invoked.)

所以,要从头到尾遵循你的代码示例,这是它的方式......

  1. series是一个函数,它接受一组函数(callbacks)和一个函数(last)作为参数。它首先被调用。

  2. series中,定义了一个名为next的函数(不要与名为next的每个回调函数的参数混淆。调用函数next

  3. next中,定义了名为callback的变量。它的值是callbacks数组中的函数之一。存储在callback变量中的函数将使用匿名函数调用。

  4. callback中,调用async函数。步骤3中的相同匿名函数将传递给async。它现在称为next,但这与next中定义的series函数没什么关系。

  5. async内,完成了一些计算,最终调用了匿名函数(通过setTimeout)。它在callback函数中称为async

  6. 在匿名函数中,某些值被推送到results数组,并调用next。这是next中定义的series函数。

  7. 重复步骤3到6,直到调用callbacks中的所有函数,然后调用参数lastfinal)中的函数。

  8. 清楚如泥,对吧?

答案 1 :(得分:1)

系列函数获取要执行的函数列表。每个函数都必须使用一个需要作为函数的参数,一个回调函数。 series使用该回调来知道函数完成了异步工作。

以下是series所做的一步一步:

  1. 获取一系列函数和一个名为last
  2. 的回调
  3. 创建一个results数组,我们将存储所有这些函数的结果
  4. 选择列表中的第一项并从列表中删除
  5. 如果项目不是函数(列表为空):
    1. 使用last数组
    2. 致电results
    3. 停止。我们已经完成了
  6. 如果该项是函数调用它并传递一个新的回调,让我们知道它何时完成
  7. 完成功能完成异步工作后,应该使用任意数量的参数调用回调。将这些参数存储在results数组
  8. 转到3
  9. 基本上,它是一个递归函数,等待每个步骤之间的进程完成。结果将是您在callbacks列表中传递的每个函数将按顺序调用,每个函数都在前一个完成其工作之后调用。

    不要气馁。即使对于经验丰富的程序员来说,异步代码也很难。