如何剖析这个JavaScript回调函数示例?

时间:2017-09-26 20:08:58

标签: javascript callback

我是JavaScript和编程的新手,我已经阅读了至少8或9个不同的示例/教程来解释回调函数。据我所知,这是一个给新程序员带来很多麻烦的概念。我理解为什么要使用它们,以及如何使用它们,但我仍然不确定我理解为什么它们的工作原理。我写了以下例子:

function a(callback) {
 setTimeout(function() {
  console.log("First");
  callback();
 }, 2000);
}

function b(callback) {
 setTimeout(function() {
  console.log("Second");
  callback();
 }, 1000);
}

function c() {
 console.log("Third");
}

function d() {
 a(function() {
  b(function() {
    c(); 
   });
 });
}

此代码作为函数首先运行,即使它花费最长,而函数b运行第二,即使它花费的时间比c长。我知道我已经插入了一个名为“回调”的参数'进入函数a和b,并且这些函数将运行我插入的任何函数来代替回调'根据'回调(),运行时的参数;'线。例如,如果我在控制台中键入a(b);,结果为First,Second。如果我在控制台中输入b(c);,我会获得第二,第三。

我并不真正理解的部分是我在功能d中所写的内容,其中我运行了所有3个功能。函数d执行函数a,但它看起来像它包含一个匿名函数作为参数,它运行函数b,它还包括一个匿名函数作为参数,它运行函数c。这是怎么回事?通过在控制台中键入a(b(c));,为什么它不起作用?

我想我并没有真正看到函数d与函数a和b中的回调参数之间的联系。具体来说,当我a(b);时,我很容易看到它是如何工作的。但是当我a(function() {b();})产生相同的结果时,我并不真正理解它为什么会起作用。

有人会解释函数d的工作原理,或者为什么a(function() {b();})与此示例中的a(b);相同?

2 个答案:

答案 0 :(得分:1)

a(function() {
  b(function() {
    c(); 
   });
});

这意味着"执行一个函数,传入一个新函数,其文本是:

function() {
  b(function() {
    c(); 
   });
}

......"。所以它产生了函数,并调用了一个。 a设置一个计时器,2秒后,它会调用你创建的功能。执行该函数时,它会找到以下指令:

b(function() {
    c(); 
});

这意味着"执行b函数,传入一个新函数,其文本是:

function() {
    c(); 
}

......"。所以接下来呢。 b被调用,它设置一个计时器,当b关闭时,它执行你传递给它的函数。作为执行该函数的一部分,它调用c。

  

为什么键入a(b(c))不起作用;进入控制台?

b(c)表示"执行b功能,传入c功能"
a(b(c))表示"执行a函数,传入b(c)的返回值"

所以当a(b(c))执行时,它会立即运行b(c),因为它需要知道它返回的内容。 b(c)设置一个计时器,然后立即返回undefined(这是隐式的,因为没有return语句)。然后将此未定义传递给a。 a设置一个计时器并返回undefined。

在大约1秒钟内,由b创建的计时器熄灭,因此它调用c(这是传递给它的。大约1秒后(从开始2秒),由a创建的计时器熄灭由于undefined被传递给a,我希望你会得到一个例外,因为undefined不是一个函数。

答案 1 :(得分:0)

  

这里发生了什么?键入(b(c))为什么它不起作用;进入控制台?

写一个(b(c));它与:

相同

A(   公元前) );

表示您正在执行a,但在此之前您执行b将c作为参数传递,这意味着:

首先执行

b b执行c a接收b作为参数,无论b返回并尝试执行它,但由于b不返回任何内容,一旦尝试执行不存在的内容,它就会给出错误"回调不是一个功能"因为undefined不是一个函数

  

我想我并没有真正看到函数d与函数a和b中的回调参数之间的联系。具体来说,当我做(b);我很容易看出它是如何工作的。但是当我做一个(function(){b();}),产生相同的结果时,我并不真正理解为什么它会起作用。

总是很有用,可以看到更多分歧:

a(
  function() {
    b();
  }
)

a被执行,并且作为参数,它接收匿名函数 a执行作为参数接收的函数(匿名函数) 然后匿名函数(并且只有那时)执行b

  

有人可以为我解剖这个并帮助我理解函数d的工作原理,或者为什么(function(){b();})与a(b)相同;在这个例子中?

在(function(){b();})中,你将匿名函数传递给a是不一样的(好吧,不完全),在这种情况下几乎不能调用b,但是匿名函数可能包含更多指令,如下所示:

a(
    function() {
        console.log("I'm no longer the same!");
        b();
    }
)

所以,如果你想要确保回调的东西多于b,那么你会(在这种情况下)使用匿名函数,但如果你只想通过a执行b,你会使用a(b);

现在,请考虑一下:

a(
    function(){}
)

它是相同的,除了功能没有做任何事情

a(
    function(){
        console.log('anonymous');
    }
)

会打印匿名,但是:

a(
    function(){
    console.log('anonymous');
  }()
)

会打印匿名,一秒后会抛出错误(回调不是函数)因为正在执行函数(注意我添加的())并且没有返回任何内容,现在让我们回答移动函数并给它起一个名字(让我们说,x):

function x(){
  console.log('anonymous');
}

a(
  x()
)

正如你所看到的,a(x())与a(x)不同,不同之处在于当你在函数前面写()时执行函数并且它(' s值是它返回的任何值,但如果你不写那个(),它只是对函数本身的引用。