2

请向我解释这是如何工作的。我是nodejs的新手,他们设置代码的方式对我来说非常复杂,无法正确理解..

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

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

我不明白上面的片段。看起来这个匿名函数成为系列匿名函数的下一个参数?匿名函数参数中的代码会执行吗?

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);
4

2 回答 2

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中,定义了一个名为的变量callbackcallbacks它的值依次是数组中的函数之一。存储在callback变量中的函数被匿名函数调用。

  4. 在 内callbackasync函数被调用。第 3 步中的相同匿名函数被传递给async. 它现在被称为next,但这与 中next定义的函数没有太大关系series

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

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

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

像泥一样清澈,对吧?

于 2012-08-30T13:29:06.830 回答
1

series 函数采用一系列要执行的函数。这些函数中的每一个都必须接受一个参数,该参数需要是一个函数,一个回调。series使用该回调来知道一个函数完成了它的异步工作。

这是一步一步的series操作:

  1. 获取一个函数列表和一个名为last
  2. 创建一个results数组,我们将在其中存储所有这些函数的结果
  3. 选择列表中的第一项并从列表中删除
  4. 如果项目不是函数(列表为空):
    1. lastresults数组调用
    2. 停止。我们完成了
  5. 如果项目是一个函数,调用它并传递一个新的回调,让我们知道它什么时候完成
  6. 一旦函数完成其异步工作,它应该使用任意数量的参数调用回调。将这些参数存储在results数组中
  7. 前往 3

基本上,它是一个递归函数,等待每个步骤之间的过程完成。结果将是您在其callbacks列表中传递的每个函数都将在前一个完成工作之后依次调用。

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

于 2012-08-30T13:19:33.170 回答