繁体   English   中英

javascript 回调只是作为函数调用中的参数发送的匿名函数吗?

[英]Are javascript callbacks just anonymous functions sent as an argument in a function call?

Javascript callbacks只是作为函数调用中的参数发送的匿名函数吗?

例如,

mySandwich('ham', 'cheese', function() {  
   alert('Finished eating my sandwich.');  
  }); 

JavaScript 回调是作为值传递给异步函数的函数,目的是继续执行。

函数是值:

因此,在 JavaScript 中,您可以传递类似值的函数。 您可以通过多种方式引用函数:

  1. 传递一个文字匿名函数作为回调

    doSomeWork(function (err, result) { if (err) { throw new Error(err); } else { console.log(result); } });
  2. 传递一个文字命名函数作为回调

    doSomeWork(function magicalCallback(err, result) { if (err) { throw new Error(err); } else { console.log(result); } });

    命名每个函数是一个聪明的主意,因为您可以在堆栈跟踪中看到它

  3. 传入一个变量的值,该变量恰好将函数存储为回调

    var someFunction = function callItWhatYouWant(err, result) { if (err) { throw new Error(err); } else { console.log(result); } } // reference the callback stored in the someFunction variable doSomeWork(someFunction);
  4. 通过引用函数名作为回调函数传入函数

    function callItWhatYouWant(err, result) { if (err) { throw new Error(err); } else { console.log(result); } } // reference the callback function using the function name doSomeWork(callItWhatYouWant);

继续?

继续就是下一步。 当你调用一个异步函数时,它需要通知你它已经完成。 回调作为下一步,即异步函数将在完成后回调您。

所以回调只是一个用于特定目的的函数参数,即延续。

回调签名

回调应该采用哪些参数没有标准,但在 Node.js 社区中,我们采用了通用签名

function (err, result)

如果发生了不好的事情, err是一个Error对象,如果事情成功,则为null 如果事情变得糟糕result通常是undefined ,否则它包含结果。 所以你的回调通常由任何一个调用

callback(new Error("oops"));

或者

callback(null, result);

另请注意,异步函数的最后一个参数作为回调参数是正常的

function callLater(delay, args, callback) {
    setTimeout(function () {     
        callback(null, args);
    }, delay);
}

在您的示例中:是

但在 m 示例中:否

function myCallback()
{
    alert('finished eating my sandwich');
}
mySandwich('ham','cheese', myCallback);

所以,根据你的评论,我认为真正的问题是:什么是匿名函数? 我已经尽力了,但这里现在还早,所以不要开枪。

嗯,很好的问题。 硬回答

在定义一个函数时,它存在于它的scope 范围? 嗯? 好吧,让我们重新开始。

加载网页时,浏览器会创建一个窗口对象。 然后它开始解析您在该文档中编写的所有内容(假设为 HTML)。

它遇到的每个 DOMElement 都会被放入window.document对象中。 widnow.document 元素中的每个元素都在浏览器窗口中呈现/解释。

现在,浏览器遇到以下<script>

var myVariable = 'So cool';

浏览器看到var myVariable 这告诉他在当前范围内创建一个名为myVariable的变量(还是那个词)。 当前范围是window (浏览器创建的窗口对象)。 所以它将变量添加到 window 对象中:

window.myVariable === myVariable

函数也是一样

function myAwesomeFunction()
{
    alert('I am so cool');
}

在当前作用域( window )内创建一个名为myAwesomeFunction 再说一遍:

window.myAwesomeFunction === myAwesomeFunction

但是如果我想创建一个我不希望任何其他代码访问的函数怎么办? 如果我想要一个只有在单击某个特定按钮时才应该存在的功能,该怎么办。

好吧,输入匿名函数。 这些是在匿名范围内声明的函数。 不能使用 window 对象访问它们:

myButton = document.getElementById('myButton'); // === window.document.getElementById('myButton');
myButton.addEventListener('click', function()
{
    alert('I am so awesome');
});

现在,您传递给 eventlistener 的函数只存在于 eventListener 中。 它甚至没有名字。 所以它的作用域是“按钮的点击事件”,但我们不能从外部访问它,因为它没有名字。 因此,匿名函数。

一个很好的读物是谷歌的东西,比如“javascript scope”、“javascript window object”……很多好文章对我扔给你的所有词提供了更好的深入解释。

是的,除了它们不必是匿名函数,而且回调的定义还有一点。 另外两个答案已经很好地涵盖了回调的用途和匿名函数的详细信息,但是当我第一次学习时,我也遇到了与您类似的困惑,所以我想添加一个缺失的部分。 所以,你的例子:

mySandwich('ham', 'cheese', function() {  
   alert('Finished eating my sandwich.');  
   }); 

我注意到大多数回调解释都是这样的——它们不包括更大函数的声明,在这种情况下是 mySandwich。 但是是的,传入的函数确实需要显式调用回调函数才能运行。 因此,您的 mySandwich 函数可能如下所示:

function mySandwich(meat, topping, callback) {
    //some code here using meat and topping
    //some code here about eating the sandwich
    callback();
}

因此,您的代码将这些参数(包括函数)传递到 mySandwich 函数中,然后该函数调用它。 因为很多时候我们使用的顶级函数是来自库的方法而不是我们自己代码的一部分,所以我们实际上并没有看到调用回调的步骤,但它仍然会发生并且不会自动发生执行自己。

所以是的,回调实际上只是一个作为参数传递给另一个函数的函数,然后它通常作为该更大函数中发生的最后一件事被调用。 回调不止于此,但它们的操作规则与其他函数相同,因为它们必须在某处被声明,在某处必须被调用,否则它们不会运行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM