簡體   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